1. 程式人生 > >淺談Java設計模式——觀察者模式(Observer)

淺談Java設計模式——觀察者模式(Observer)

一、概述

        定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。觀察者模式定義了物件之間的一對多依賴關係,這樣一來,當一個物件改變狀態時,它的所有依賴者都會收到通知並且自動更新。在這裡,發生改變的物件稱之為觀察目標,而被通知的物件稱之為觀察者。一個觀察目標可以對應多個觀察者,而且這些觀察者之間沒有相互聯絡,所以麼可以根據需要增加和刪除觀察者,使得系統更易於擴充套件。所以觀察者提供了一種物件設計,讓主題和觀察者之間以鬆耦合的方式結合。

二、使用場景

1.當一個抽象模型有兩個方面,其中一個方面依賴於另一方面。 將這二者封裝在獨立的物件中以使它們可以各自獨立地改變和複用。 

2.當對一個物件的改變需要同時改變其它物件,而不知道具體有多少物件有待改變。 

3.當一個物件必須通知其它物件,而它又不能假定其它物件是誰。

三、參與者

1.Subject (目標)目標知道它的觀察者。可以有任意多個觀察者觀察同一個目標。 提供註冊和刪除觀察者物件的介面。

2.Observer (觀察者)為那些在目標發生改變時需獲得通知的物件定義一個更新介面。 

3.ConcreteSubject (具體目標)將有關狀態存入各ConcreteObserver物件。 當它的狀態發生改變時,向它的各個觀察者發出通知。 

4.ConcreteObserver (具體觀察者)維護一個指向ConcreteSubject物件的引用。 儲存有關狀態,這些狀態應與目標的狀態保持一致。 實現     Observer的更新介面以使自身狀態與目標的狀態保持一致

四、類圖

五、示例程式碼

1.Subject

/**
 * Subject
 * @author zhipeng_Tong
 */
public abstract class Subject {
    private ArrayList<Observer> observers = new ArrayList<>();

    // 新增觀察者
    public void add(Observer observer) {
        observers.add(observer);
    }

    // 移除觀察者
    public void remove(Observer observer) {
        observers.remove(observer);
    }

    // 通知
    public void toNotify() {
        for (Observer observer : observers)
            observer.update();
    }
}

2.Observer

/**
 * Observer
 * @author zhipeng_Tong
 */
public interface Observer {
    void update();
}

3.ConcreteSubject

/**
 * ConcreteSubject
 * @author zhipeng_Tong
 */
public class Boss extends Subject {
    private String subjectState;    // 儲存狀態資訊

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
    }
}

4.ConcreteObserver 

/**
 * ConcreteObserver
 * @author zhipeng_Tong
 */
public class StockObserver implements Observer {
    private String name;    // 名稱
    private String observerState;   // 狀態
    private Boss subject;    // 通知者

    public StockObserver(String name, Boss subject) {
        this.name = name;
        this.subject = subject;
    }

    @Override
    public void update() {
        observerState = subject.getSubjectState();
        System.out.println(String.format("%s - %s 關閉股票軟體,繼續工作。", observerState, name));
    }
}

5.測試程式碼

public class Client {
    public static void main(String[] args) {
        Boss boss = new Boss();

        boss.add(new StockObserver("李傳華", boss));
        boss.add(new StockObserver("周大海", boss));

        boss.setSubjectState("老闆回來了");
        boss.toNotify();
    }
}

執行結果:

老闆回來了 - 李傳華 關閉股票軟體,繼續工作。
老闆回來了 - 周大海 關閉股票軟體,繼續工作。