設計模式之觀察者模式

前言

Observer本來的意思是“觀察者”,但是實際上Observer角色並非主動的去觀察,而是被動的接收來自觀察對象角色的通知,因此,Observer也被成爲Publish-Subscribe(發佈-訂閱)模式。它定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態上發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。對於觀察者模式應用的也很多,例如大家最熟悉的MVC框架就是觀察者模式的典型應用,消息推送,事件監聽等都是觀察者模式的最好詮釋。

在圖解設計模式中是通過一個觀察者觀察一個會生成數值的對象,並將生成的數值通過不同的觀察者顯示出來。照例通過如下UML類圖簡單熟知下流程。

這裏寫圖片描述

觀察者Observer

Observer角色負責接收來自觀察者對象角色的狀態變化的通知,它表示“觀察者”,具體的觀察者會實現該接口,用於生成數字的觀察對象角色類NumberGenerator類會調用update方法並且將生成的數字變化的通知發送給Observer。

public interface Observer {
    public abstract void update(NumberGenerator generator);
}

觀察對象NumberGenerator

該類是用於生成數值的抽象類,提供了獲取數值和生成數值的抽象方法,需要子類去實現。並且提供了一個存放觀察數值變化的觀察者對象的List。方法addObserver(Observer observer)和deleteObserver(Observer observer)用註冊觀察者和刪除觀察者,重要的一步就是當有數據變化時調用notifyObservers方法通知所有觀察者。

public abstract class NumberGenerator {
    private ArrayList observers=new ArrayList();
    public void addObserver(Observer observer){
        observers.add(observer);
    }
    public void deleteObserver(Observer observer){
        observers.remove(observer);
    }
    public void notifyObservers(){
        Iterator iterator=observers.iterator();
        while (iterator.hasNext()){
            Observer observer= (Observer) iterator.next();
            observer.update(this);
        }
    }
    public abstract int getNumber();
    public abstract void execute();
}

具體的觀察對象RandomNumberGenerator

對於該具體觀察者對象,它主要是用來生成隨機數,並通過notifiObservers方法把每一次生成的結果通知給所有已註冊的觀察者

public class RandomNumberGenerator extends NumberGenerator {
    private Random random = new Random();
    private int number;

    @Override
    public int getNumber() {
        return number;
    }

    @Override
    public void execute() {
        for (int i = 0; i < 5; i++){
            number=random.nextInt(30);
            notifyObservers();
        }
    }
}

具體觀察者

具體觀察者實現了觀察者Observer接口,當update方法被調用時會去獲取要觀察的對象的最新數據,在此寫了兩個具體的觀察者。

public class DigitObserver implements Observer{
    @Override
    public void update(NumberGenerator generator) {
        System.out.println("DigitObserver:"+generator.getNumber());
    }
}

public class GraphObserver implements Observer{
    @Override
    public void update(NumberGenerator generator) {
        System.out.println("GraphObserver:"+generator.getNumber());
    }
}

測試類

public class Main {
    public static void main(String[] args) {
        NumberGenerator generator=new RandomNumberGenerator();
        Observer observer1=new DigitObserver();
        Observer observer2=new GraphObserver();
        generator.addObserver(observer1);
        generator.addObserver(observer2);
        generator.execute();
    }
}

輸出信息:

DigitObserver:2
GraphObserver:2
DigitObserver:19
GraphObserver:19
DigitObserver:26
GraphObserver:26
DigitObserver:10
GraphObserver:10
DigitObserver:14
GraphObserver:14

通過上面測試代碼,你應該發現對於觀察者對象可以有多個觀察者對其作出響應,如某些訂閱專欄,它可以被很多人訂閱,當專欄有內容更新時,它會給每一個人發送推送,我們在訂閱專欄後,並不需要我們一直去等待它的內容更新,而不能去做自己的事情。

好了,今天的觀察者模式到此結束。有問題歡迎留言指出,Have a wonderful day .

發佈了47 篇原創文章 · 獲贊 42 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章