天天看點

圖解設計模式 - Observer 模式

讀書筆記 僅供參考

簡述

觀察者模式,當觀察對象的狀态發生變化時,會通知給觀察者。适用于根據對象狀态進行相應處理的場景。

角色和 UML

Subject

該角色表示觀察對象,定義了注冊觀察者和删除觀察者的方法,同時聲明了擷取現在狀态的方法。

ConcreteSubject

具體的被觀察對象,自身狀态改變後,會通知已經注冊的 Observer 對象。

Observer

負責接收來自 Subject 角色的狀态變化的通知。

ConcreteObserver

具體的 Observer,當它的 update 方法被調用後,回去擷取要觀察的對象的最新狀态。

UML

圖解設計模式 - Observer 模式

例子

例程是一個自動生成數字,通知觀察者展示數字的程式。

public interface Observer {
    //讓被觀察者通知觀察者狀态已經改變
    void update(NumberGenerator generator);
}           
// 以數字形式顯示觀察到的數值
public class DigitObserver implements Observer {

    @Override
    public void update(NumberGenerator generator) {
        System.out.println("DigitObserver: " + generator.getNumber());
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {

        }
    }
}
           
// 将觀察到的數值以 ***** 的方式顯示出來
public class GraphObserver implements Observer {

    @Override
    public void update(NumberGenerator generator) {
        System.out.println("GraphObserver: ");
        int count = generator.getNumber();
        for (int i = 0; i < count; i++){
            System.out.print("*");
        }
        System.out.println();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {

        }
    }
}           
//作為 Subject 被觀察者
public abstract class NumberGenerator {
    private List<Observer> observers = new ArrayList<>();

    public void addObservers(Observer observer) {
        observers.add(observer);
    }

    public void deleteObserver(Observer observer) {
        observers.remove(observer);
    }

    // 向 Observer 發生通知
    public void notifyObserers() {
        Iterator<Observer> it = observers.iterator();
        while (it.hasNext()) {
            Observer o = it.next();
            o.update(this);
        }
    }

    //擷取數值
    public abstract int getNumber();

    //生成數值
    public abstract void execute();
}
           
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 < 20; i++) {
            number = random.nextInt(50);
            notifyObserers();
        }
    }
}           
public class Main {
    public static void main(String[] args) {
        NumberGenerator generator = new RandomNumberGenerator();
        Observer observer1 = new DigitObserver();
        Observer observer2 = new GraphObserver();
        generator.addObservers(observer1);
        generator.addObservers(observer2);
        generator.execute();
    }
}           

結果

圖解設計模式 - Observer 模式

UML

圖解設計模式 - Observer 模式

要點

  • 實作了可替換性,Subject 不用關注 Observer 的實作
  • Observer 可能會有一定的順序要求
  • 當 Observer 對 Subject 産生影響時,注意産生循環調用
  • Observer 并不是主動的去觀察,而是被動的接收通知

繼續閱讀