1. 程式人生 > >設計模式--觀察者模式(釋出訂閱模式)

設計模式--觀察者模式(釋出訂閱模式)

類圖

這裡寫圖片描述

定義
定義物件間一種一對多的依賴關係,使得每當一個物件改變狀態,則所有依賴於它的物件都會得到通知並被自動更新

優點
- 觀察者和被觀察者之間是抽象耦合。如此,則不管是增加觀察者還是被觀察者都易擴充套件
- 建立一套觸發機制 觀察者模式可以完美地實現鏈條形式

缺點
- 一個被觀察者,多個觀察者,開發和除錯比較複雜
- JAVA 中訊息的通知預設是順序執行,其中一個出問題,會影響整體執行效率
- 多級觸發時的效率更加令人擔憂

使用場景
- 時間多級觸發場景
- 跨系統的訊息交換場景,如訊息佇列的處理機制

擴充套件
觀察者模式和責任鏈模式的區別:觀察者模式在傳播的過程中訊息是隨時更改的,
它是由相鄰兩個節點協商的訊息結構,而責任鏈模式在訊息傳遞過程中基本上保持訊息不可變

首先我們要定義觀察者的更新操作介面,這個介面主要是為了獲得被觀察者變化的訊息。

public interface Observer {
    void update();
}

實現觀察者

public class ConcreteObserver implements Observer {
    /**
     * 實現更新方法
     */
    @Override
    public
void update() { System.out.println("<我是觀察者>:\n接收到訊息,並處理訊息"); } }

定義被觀察者的抽象類

public abstract class Subject {
    /**
     * 定義一個觀察者陣列
     */
    private Vector<Observer> obsVector = new Vector<>();

    /**
     * 新增觀察者
     *
     * @param o 觀察者
     */
    public void
addObserver(Observer o) { obsVector.add(o); } /** * 刪除觀察者 * * @param o 觀察者 */ public void delObserver(Observer o) { obsVector.remove(o); } /** * 把被觀察者的動作分發到所有的觀察者 */ public void notifyObservers() { for (Observer o : obsVector) { o.update(); } } }

實現被觀察者

public class ConcreteSubject extends Subject {
    /**
     * 具體的業務
     */
    public void doSomething() {
        System.out.println("<我是被觀察者>:\nConcreteSubject->doSomething()");
        // 觀察者做完了事情,把訊息分發給所有的觀察者
        super.notifyObservers();
    }
}

測試場景類

public class Client {
    public static void main(String[] args) {
        // 定義一個被觀察者
        ConcreteSubject subject = new ConcreteSubject();
        // 定義一個觀察者
        Observer obs = new ConcreteObserver();
        // 觀察者觀察被觀察者
        subject.addObserver(obs);
        // 被觀察者做了一些事情
        subject.doSomething();
    }
}

執行結果:

<我是被觀察者>:
ConcreteSubject->doSomething()
<我是觀察者>:
接收到訊息,並處理訊息