Java設計模式之觀察者模式

前言

觀察者模式又被成爲發佈-訂閱模式, 屬於行爲型設計模式的一種,是一個在項目中經常使用的模式。

定義

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

使用場景

  • 關聯行爲場景。需要注意的是,關聯行爲是可拆分的,而不是“組合”關係。
  • 事件多觸發場景。
  • 跨系統的消息交換場景,如消息隊列、事件總線的處理機制。

角色

  • Subject:抽象主題(抽象被觀察者)。抽象主題角色把所有觀察者對象保存在一個集合裏,每個主題都可以有任意數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象。
  • ConcreteSubject:具體主題(具體被觀察者)。該角色將有關狀態存入具體觀察者對象,在具體主題的內部狀態發生改變時,給所有註冊過的觀察者發送通知。
  • Observer:抽象觀察者,是觀察者的抽象類。它定義一個更新接口,使得在得到主題更改通知時更新自己。
  • ConcrereObserver:具體觀察者,實現抽象觀察者定義的更新接口,以便在得到主題更改通知時更新自身的狀態。

觀察者模式的簡單實現

微信公衆號場景:假設微信用戶就是觀察者,微信公衆號是被觀察者,有多個微信用戶關注了“程序員”這個公衆號。當這個公衆號更新時就會通知這些訂閱的用戶。

  1. 抽象觀察者:裏面定義一個更新方法。
public interface Observer {
     void update(String message);
}
  1. 具體觀察者:微信用戶是觀察者,裏面實現了更新的方法。
public class WeChatUser implements Observer {
    private String name;
    public WeChatUser(String name){
        this.name = name;
    }
    @Override
    public void update(String message) {
        System.out.println(name + " " + message);
    }
}
  1. 抽象被觀察者:被觀察者,提供 attachdetachnotify三個方法。
public interface Subject {
    /**
     * 增加訂閱者
     * @param observer
     */
    void attach(Observer observer);

    /**
     * 刪除訂閱者
     * @param observer
     */
    void detach(Observer observer);

    /**
     * 通知訂閱者更新消息
     * @param message
     */
    void notify(String message);

}

  1. 具體被觀察者:微信公衆號具體主題(具體被觀察者),裏面存儲了訂閱該公衆號的微信用戶,並實現了抽象主題中的方法。
public class SubscriptionSubject implements Subject {

    private List<Observer> weChatUserList = new ArrayList<Observer>();
    @Override
    public void attach(Observer observer) {
        weChatUserList.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        weChatUserList.remove(observer);
    }

    @Override
    public void notify(String message) {
        for(Observer observer : weChatUserList){
            observer.update(message);
        }
    }
}
  1. 客戶端調用
public class Client {
    public static void main(String[] args) {
        SubscriptionSubject mSubscriptionSubject = new SubscriptionSubject();
        //創建微信用戶
        WeChatUser user1 = new WeChatUser("用戶1");
        WeChatUser user2 = new WeChatUser("用戶2");
        WeChatUser user3 = new WeChatUser("用戶3");
        //訂閱公衆號
        mSubscriptionSubject.attach(user1);
        mSubscriptionSubject.attach(user2);
        mSubscriptionSubject.attach(user3);
        //公衆號更新發出消息給訂閱的微信用戶
        mSubscriptionSubject.notify("公衆號有更新內容了");
    }
}

優缺點

優點

  • 觀察者和被觀察者之間是抽象耦合,容易擴展。
  • 方便建立一套觸發機制。

缺點

  • 在應用觀察者模式時需要考慮一下開發效率和運行效率的問題。程序中包括一個被觀察者和多個觀察者,開發、調試等內容比較複雜,而且在 Java 中消息的通知一般是有執行順序的,那麼一個觀察者卡頓,會影響整體的執行效率,這種情況下一般會採用異步方式。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章