觀察者模式 JAVA設計模式之觀察者模式

定義

當對象間存在一對多關係時,則使用觀察者模式(Observer Pattern)。好比,當一個對象被修改時,則會自動通知它的依賴對象。觀察者模式屬於行爲型模式。html

解釋:簡單來講對象 A 須要關注對象 B 的狀態,根據對象 B 的不一樣狀態來作一些調整。好比播放器的 UI 變化,會依賴當前的播放狀態,一旦播放狀態改變了,就須要調整 UI 的顯示。java

使用場景

  • 一個抽象模型有兩個方面,其中一個方面依賴於另外一個方面。將這些方面封裝在獨立的對象中使它們能夠各自獨立地改變和複用。
  • 一個對象的改變將致使其餘一個或多個對象也發生改變,而不知道具體有多少對象將發生改變,能夠下降對象之間的耦合度。編程

  • 一個對象必須通知其餘對象,而並不知道這些對象是誰。設計模式

  • 須要在系統中建立一個觸發鏈,A對象的行爲將影響B對象,B對象的行爲將影響C對象……,能夠使用觀察者模式建立一種鏈式觸發機制。

 具體實踐

根據上面說的,下面咱們來實現一個簡單的觀察者模式。微信

 觀察者

先定義一個觀察者接口,具體的觀察者都須要實現該接口。異步

package com.sjq.observer;

/***
 * 抽象觀察者
 * 定義了一個update()方法,當被觀察者調用notifyObservers()方法時,觀察者的update()方法會被回調。*/
public interface Observer {
    public void update(String message);
}

接着,就是一個具體的觀察者,在 update 中添加數據改變後的操做邏輯。ide

package com.sjq.observer;

/**
 * 觀察者
 * 實現了update方法
*/
public class User implements Observer {

    private String name;
    private String message;
    
    public User(String name) {
        this.name = name;
    }
    
    @Override
    public void update(String message) {
        this.message = message;
        read();
    }
    
    public void read() {
        System.out.println(name + " 收到推送消息: " + message);
    }
    
}

 被觀察者

一樣的,須要定義一個被觀察者接口,全部具體的被觀察者對象都須要實現該接口。post

package com.sjq.observer;

/***
 * 抽象被觀察者接口
 * 聲明瞭添加、刪除、通知觀察者方法
 */
public interface Observerable {
    
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObserver();
    
}

 定義具體的被觀察者對象,實現了 Observerable 接口,對 Observerable 接口的三個方法進行了具體實現,同時有一個 List 集合,用以保存註冊的觀察者,等須要通知觀察者時,遍歷該集合便可。測試

package com.sjq.observer;

import java.util.ArrayList;
import java.util.List;

/**
 * 被觀察者,也就是微信公衆號服務
 * 實現了Observerable接口,對Observerable接口的三個方法進行了具體實現
 */
public class WechatServer implements Observerable {
    
    //注意到這個List集合的泛型參數爲Observer接口,設計原則:面向接口編程而不是面向實現編程
    private List<Observer> list;
    private String message;
    
    public WechatServer() {
        list = new ArrayList<Observer>();
    }
    
    @Override
    public void registerObserver(Observer o) {
        
        list.add(o);
    }
    
    @Override
    public void removeObserver(Observer o) {
        if(!list.isEmpty())
            list.remove(o);
    }

    //遍歷
    @Override
    public void notifyObserver() {
        for(int i = 0; i < list.size(); i++) {
            Observer oserver = list.get(i);
            oserver.update(message);
        }
    }
    
    public void setInfomation(String s) {
        this.message = s;
        System.out.println("微信服務更新消息: " + s);
        //消息更新,通知全部觀察者
        notifyObserver();
    }

} 

代碼測試

完成上面的工做以後,我們就能夠測試我們寫的代碼了,看看能不能跑起來。具體以下:this

package com.sjq.observer;

public class Test {
    
    public static void main(String[] args) {
        WechatServer server = new WechatServer();
        
        Observer userZhang = new User("ZhangSan");
        Observer userLi = new User("LiSi");
        Observer userWang = new User("WangWu");
        
        server.registerObserver(userZhang);
        server.registerObserver(userLi);
        server.registerObserver(userWang);
        server.setInfomation("PHP是世界上最好用的語言!");
        
        System.out.println("----------------------------------------------");
        server.removeObserver(userZhang);
        server.setInfomation("JAVA是世界上最好用的語言!");
        
    }
} 

注意事項: 

  • JAVA 中已經有了對觀察者模式的支持類。

  • 避免循環引用。

  • 若是順序執行,某一觀察者錯誤會致使系統卡殼,通常採用異步方式。

Android 中的應用

  •  Android 中 Adapter 應用普遍,其實在 adapter 中就存在觀察者模式得應用。好比 ListView, 當咱們調用 setAdapter() 時候,內部是經過觀察者模式來通知數據變化的,當數據發生變化,就會通知 ListView 自身去從新繪製。

  • BrocastReceive 廣播。有動態註冊和靜態註冊,其實也是觀察者模式得一種應用。

  • 另外常常可見一些 addXXXListener 方法,其實這類也能夠當作是觀察者的一種體現。 

參考文獻

一、http://www.runoob.com/design-pattern/observer-pattern.html

二、JAVA設計模式之觀察者模式

相關文章
相關標籤/搜索