1. 程式人生 > >觀察者設計模式解讀

觀察者設計模式解讀

觀察者模式是一個使用率非常高的模式,它常用的地方是GUI系統、訂閱—-釋出系統。因為這個模式的一個重要作用就是解耦,將被觀察者和觀察者解耦,使得它們之間的依賴性更小,甚至做到毫無依賴。

定義

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

UML圖

Observer UML

  • Subject
    抽象主題,也就是被觀察者(Observable)的角色,抽象主題角色把所有觀察者物件的引用儲存在一個集合裡,每個主題都可以有任意數量的觀察者,抽象主題提供一個介面,可以增加和刪除觀察者物件
  • ConcreteSubject
    具體主題,該角色將有關狀態存入具體觀察者物件,在具體主題的內部狀態發生改變時,給所有註冊過的觀察者發出通知,具體主題角色又叫具體被觀察者(ConcreteObservable)角色
  • Observer
    抽象觀察者,該角色是觀察者的抽象類,它定義了一個更新介面,使得在得到主題的更改通知時更新自己
  • ConcreteObserver
    具體的觀察者。該角色實現抽象觀察者角色所定義的更新介面,以便在主題狀態發生變化時更新自身的狀態

觀察者模式程式碼實現(Java)

抽象被觀察者


public abstract class Subject {

    // 定義一個觀察者陣列
    private Vector<Observer> obs = new Vector<>();

    // 增加一個觀察者
    public void addObserver
(Observer o) { this.obs.add(o); } // 刪除一個觀察者 public void delObserver(Observer o) { this.obs.remove(o); } // 通知所有觀察者 public void notifyObservers() { for (Observer o : this.obs) { o.update(); } } public abstract void doSomeThing
(); }

具體被觀察者

public class ConcreteSubject extends Subject{

    @Override
    public void doSomeThing() {
        // TODO 被觀察者 處理具體業務邏輯
        System.out.println("被觀察者處理業務邏輯 ,並通知觀察者");
        // 通知觀察者 
        super.notifyObservers();
    }

}

觀察者

public interface Observer {
    // 更新方法
    public void update();
}

具體觀察者

public class ConcreteObserver implements Observer{
    @Override
    public void update() {
        // 觀察者處理具體業務邏輯
        System.out.println("觀察者接到資訊,並處理");  
    }
}

觀察者模式呼叫

public class ObserverPatterns {

    public static void main(String[] args) {
        ConcreteSubject observed = new ConcreteSubject();
        Observer observer=new ConcreteObserver();
        observed.addObserver(observer);
        observed.doSomeThing();
    }
}

適用場景

  1. 關聯行為場景
  2. 事件多級出發場景
  3. 跨系統的訊息交換場景,如訊息佇列、事件匯流排的處理機制

總結

觀察者模式主要的作用就是物件解耦,將觀察者與被觀察者完全隔離,只依賴於Observer和Observable抽象

優點

  • 觀察者和被觀察者之間是抽象耦合,應對業務變化
  • 增強系統的靈活性、可拓展性

缺點

在應用觀察者模式時需要考慮一下開發效率和執行效率問題,程式中包含一個被觀察者,多個觀察者、開發和除錯等內容會比較複雜,而且在JAVA中訊息的通知預設是順序執行,一個觀察者卡頓,會影響整體的執行效率,在這種情況下,一般採用非同步的方式