1. 程式人生 > >設計模式學習——觀察者模式

設計模式學習——觀察者模式

觀察者模式

  1. 定義:定義物件間一種一對多的依賴關係,使得每當一個物件發生變化時,則所有依賴於他的物件都會得到通知並自動更新。
  2. 使用場景
  • 關聯行為場景
  • 事件多級觸發場景
  • 跨系統的訊息交換場景,如訊息佇列、事件匯流排的處理機制
  1. 特點:實現物件的解耦,將觀察者和被觀察者完全隔離,只依賴於Observe和Observable抽象。
    UML
    在這裡插入圖片描述

  2. 簡單實現例子

  • 抽象觀察者類
/**
 *  抽象觀察者類,為所有具體觀察者定義一個介面,在得到通知時更新自己
 */
public interface Observer {
     /**
     *  有更新 
     *  @param message 訊息
     */
     public void update(String message);
}
  • 抽象被觀察者
/**
 * 抽象被觀察者類
 */
public interface Observable {/**
     * 推送訊息
     * @param message 內容
     */
    void push(String message);
    /**
     * 訂閱方法,提供給訂閱者訂閱
     * @param observer 訂閱者
     */
    void register(Observer observer);
}
  • 具體的觀察者類
/**
 * 具體的觀察者類,也就是訂閱者
 */
public class User implements Observer {
  /**被觀察者發生變化後觀察者要做出的反應**/
    @Override
    public void update(String message) {
        System.out.println(name + "," + message + "更新了!");
    }
    // 訂閱者的名字private String name;
    public User(String name) {
        this.name = name;
    }
}
  • 具體的被觀察者類
/**
 *  具體的被觀察者類,也就是訂閱的節目
 */
public class Teleplay implements Observable{
  private List<Observer> list = new ArrayList<Observer>();//儲存訂閱者
  @Override
  public void push(String message) {
        for(Observer observer:list){
            observer.update(message);
        }
    }
    @Overridepublic void register(Observer observer) {
        list.add(observer);
    }
}
  • 使用
public class Client {
    public static void main(String[] args) {
        //被觀察者,這裡就是使用者訂閱的電視劇
        Teleplay teleplay = new Teleplay();
        //觀察者,這裡就是訂閱使用者
        User user1 = new User("小明");
        User user2 = new User("小光");
        User user3 = new User("小蘭");
        //訂閱
        teleplay.register(user1);
        teleplay.register(user2);
        teleplay.register(user3);
        //推送新訊息
        teleplay.push("xxx電視劇");
    }
}

列印結果:

小明,xxx電視劇更新了!
小光,xxx電視劇更新了!
小蘭,xxx電視劇更新了! 

Observe 和Observable都是JDK中的內建型別,可見觀察者模式非常重要。達到一對多的通知功能,通知系統都是依賴Observe 和Observable的。

  1. 安卓中使用的觀察者模式
  • ListView

首先在Android中,我們往ListView新增資料後,都會呼叫Adapter的notifyDataChanged()方法,其中使用了觀察者模式。

當ListView的資料發生變化時,呼叫Adapter的notifyDataSetChanged函式,這個函式又會呼叫DataSetObservable的notifyChanged函式,這個函式會呼叫所有觀察者( )的onChanged方法,在onChanged函式中又會呼叫ListView重新佈局的函式使得ListView重新整理介面。

  • 廣播

Android中應用程式傳送廣播的過程:

通過sendBroadcast把一個廣播通過Binder傳送給ActivityManagerService,ActivityManagerService根據這個廣播的Action型別找到相應的廣播接收器,然後把這個廣播放進自己的訊息佇列中,就完成第一階段對這個廣播的非同步分發。
ActivityManagerService在訊息迴圈中處理這個廣播,並通過Binder機制把這個廣播分發給註冊的ReceiverDispatcher,ReceiverDispatcher把這個廣播放進MainActivity所線上程的訊息佇列中,就完成第二階段對這個廣播的非同步分發:
ReceiverDispatcher的內部類Args在MainActivity所在的執行緒訊息迴圈中處理這個廣播,最終是將這個廣播分發給所註冊的BroadcastReceiver例項的onReceive函式進行處理。

  • 事件匯流排 ——EvenBus框架