Java設計模式之觀察者模式

前言

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

定義

定義對象間一種一對多的依賴關係,每當一個對象改變狀態時,則全部依賴它的對象都會獲得通知並被自動更新。設計模式

使用場景

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

角色

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

觀察者模式的簡單實現

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

  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 中消息的通知通常是有執行順序的,那麼一個觀察者卡頓,會影響總體的執行效率,這種狀況下通常會採用異步方式。
相關文章
相關標籤/搜索