觀察者模式(Observer Pattern)也叫作發佈-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式。這個模式的一個最重要的做用就是解耦。也就是將被觀察者和觀察者進行解耦,使得他們之間的依賴性更小,甚至作到毫無依賴。java
觀察者模式的定義:該模式定義了對象之間的一對多依賴關係,Subject 對象是一,Observer 對象是多。當 Subject 對象的狀態發生改變時,全部依賴於該 Subject 對象的 Observer 對象都會獲得通知,而且自動更新。多線程
仔細分析定義,要精確理解觀察者模式主要注意三點:ide
定義了對象間的一對多依賴關係。this
當 Subject 對象的狀態發生改變時,全部依賴於該 Subject 對象的 Observer 對象都會獲得通知。線程
Observer 對象獲得通知後,會自動更新,而不是被動。code
通過上面的分析,下面我用代碼簡單實現上述邏輯。server
1.首先須要定義一個觀察者對象,內部含有data數據(getter、setter、構造方法、toString)。對象
public class Observer { private String data; public Observer(String data) { this.data = data; } public String getData() { return data; } public void setData(String data) { this.data = data; } @Override public String toString() { return "Observer{" + "data='" + data + '\'' + '}'; } }
2.其次定義主題對象,主題對象內部提供觀察者綁定(register)的接口,而且能夠更新(update)所綁定的觀察者對象。繼承
public class Subject { private List<Observer> list = new ArrayList<>(); public void register(Observer observer){ list.add(observer); } public void update(){ list.forEach(observer -> { observer.setData("new"); System.out.println(observer.toString()); }); } }
3.最後就是main方法。接口
public static void main(String[] args) { Subject subject = new Subject(); for (int i = 0; i < 3; i++) { Observer observer = new Observer("old"); subject.register(observer); System.out.println(observer.toString()); } System.out.println("update..."); subject.update(); }
控制檯打印
Observer{data='old'} Observer{data='old'} Observer{data='old'} update... Observer{data='new'} Observer{data='new'} Observer{data='new'}
看到這裏你也許會問:這就是觀察者模式?這麼簡單?你莫不是在逗我?
是的,這就是觀察者模式。咱們從觀察者模式的定義出發,抽取出關鍵的3點核心思想,對比代碼和三點思想,是否是完美一致?百度一下"觀察者模式",實現邏輯大都是複雜高深,其實就核心的思想來講,上面的示例足夠了,其它擴展要以具體的業務需求來決定。好比:
Subject 角色是應該定義成類?好比 內置的 java.util.Observable;仍是應該定義成接口,以規避Java不支持多重繼承的問題?
應該在何時訂閱主題(或者說註冊觀察者)?是實例化觀察者對象的同時?仍是由客戶自主決定?
是否應該實現取消訂閱功能(或者說取消註冊)?
主題對象通知觀察者時,是否攜帶消息?換句話說,是「推」消息?仍是「拉」消息?
是否支持多線程?