1. 程式人生 > >設計模式之觀察者模式(釋出/訂閱模式:publish/subscribe)

設計模式之觀察者模式(釋出/訂閱模式:publish/subscribe)

定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某一個主題物件.這個主題物件在狀態發生變化時,會通知所有觀察者物件,使它們能夠自動更新自己

觀察者模式的關鍵物件是主題Subject和觀察者Observer.一個Subject可以有任意數目依賴它的Observer,

一旦Subject的狀態發生了改變,所有的Observer都可以得到通知.Subject發出通知的時候並不需要知道誰是它的Observer.

而且任何具體的觀察者也不知道其他觀察者是什麼

觀察者模式的使用場景

當一個物件的改變需要同時改變其他物件,並且不需要知道具體多少需要改變

Subject類,可翻譯為主題或抽象通知者,一般用一個抽象類或者一個介面實現.它把所有對觀察者物件的引用儲存在一個聚集裡,每個主題都可以有任何數量的觀察者.
抽象主題提供一個介面,可以增加和刪除觀察者物件.

Observer類,抽象觀察者,為所有的具體觀察者定義一個介面,在得到主題的通知時更新自己.這個介面叫做更新介面.抽象觀察者一般用一個抽象類或者一個介面實現.
更新介面通常包含一個Update()方法,這個方法叫做更新方法.

ConcreteSubject類,叫做具體主題或具體通知者,將有關狀態存入具體觀察者物件;在具體主題的內部狀態改變時,給所有登記過的觀察者發出通知.
具體主題角色通常用一個具體子類實現

    public static void main(String[] args) {
        SubscriptionSubject mSubscriptionSubject=new SubscriptionSubject();
        //建立微信使用者
        WeixinUser user1=new WeixinUser("a");
        WeixinUser user2=new WeixinUser("b");
        WeixinUser user3=new WeixinUser("c");
        //訂閱公眾號
        mSubscriptionSubject.add(user1);
        mSubscriptionSubject.add(user2);
        mSubscriptionSubject.add(user3);
        mSubscriptionSubject.notify("d的專欄更新了");
    }

/**
 * 微信使用者是觀察者,微信公眾號是被觀察者,有多個的微信使用者關注了一個公眾號
 * 當這個公眾號更新時就會通知這些訂閱的微信使用者
 *抽象觀察類
 * @author guk
 *
 */
public interface Observer {
    public void update(String message);
}

/**
 * 具體觀察者 ConcreteObserver
 * @author guk
 *
 */
public class WeixinUser implements Observer {
    //微信使用者名稱
    private String name;
    
    public WeixinUser(String name) {
        super();
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name+"-"+message);
    }
}

/**
 * 抽象被觀察者類Subject
 * @author guk
 *
 */
public interface Subject {
    
    /**
     * 增加訂閱者
     * @param observer
     */
    void add(Observer observer);
    /**
     * 刪除訂閱者
     * @param observer
     */
    void delete(Observer observer);
    /**
     * 通知訂閱者更新訊息
     * @param message
     */
    void notify(String message);
}
 

/**
 * 具體被觀察者(ConcreteSubject)
 * @author guk
 *
 */
public class SubscriptionSubject implements Subject {
    //儲存訂閱公眾號的微信使用者
    private List<Observer> weixinUserList=new ArrayList<Observer>();
    
    @Override
    public void add(Observer observer) {
        weixinUserList.add(observer);
    }

    @Override
    public void delete(Observer observer) {
        weixinUserList.remove(observer);
    }

    @Override
    public void notify(String message) {
        for(Observer observer:weixinUserList) {
            observer.update(message);
        }
    }

}