觀察者模式又稱爲發佈/訂閱(Publish/Subscribe)模式。java
觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知全部觀察者對象,使它們可以自動更新本身。編程
Observerable:被觀察者接口,規定了幾個方法,分別是registerObserver():表示將觀察者註冊到被觀察者中,即「訂閱」;removeObserver():表示將觀察者從被觀察者中移除,即「取消訂閱」;notifyObservers():當被觀察者狀態改變的時候,這個方法被調用,通知全部已經註冊的觀察者。ide
ConcreteObserverable:被觀察者,實現了Observerable接口,對以上的三個方法進行了具體實現,同時有一個List集合,用以保存註冊的觀察者,等須要通知觀察者時,遍歷該集合便可。注意,該集合的泛型參數應該是Observer,接口類型,而不該該是具體的Observer實現類,這樣作的緣由是一個被觀察者可能會有多個不一樣實現類的觀察者(但都實現了Observer接口),若是限定了某一個具體的類型,那麼會致使之後要加入新類型的時候而不得不修改當前類,耦合度太高,這是一個很是很差的行爲。(設計原則:面向接口編程而不是面向實現編程)。this
Observer:觀察者接口,規定了update()方法,當被觀察者調用notifyObservers()方法時,觀察者的update()方法會被回調。spa
ConcreteObserver:觀察者,實現了update()方法。設計
//定義被觀察者 public interface Observerable { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); } //定義觀察者 public interface Observer { public void update(int edition, float cost); } public class MagazineData implements Observerable { private List<Observer> observerList; private int edition; private float cost; public MagazineData(){ observerList = new ArrayList<>(); } @Override public void registerObserver(Observer observer) { observerList.add(observer); } @Override public void removeObserver(Observer observer) { int i = observerList.indexOf(observer); if(i >=0){ observerList.remove(i); } } @Override public void notifyObservers() { observerList.stream().forEach(item ->{ item.update(edition, cost); }); } public void setInfomation(int edition, float cost){ this.edition = edition; this.cost = cost; notifyObservers(); } } public class Customer implements Observer{ private String name; private int edition; private float cost; public Customer(String name){ this.name = name; } @Override public void update(int edition, float cost) { this.edition = edition; this.cost = cost; buy(); } public void buy(){ System.out.println(name+"購買了第"+edition+"期的雜誌,花費了"+cost+"元。"); } } public static void main(String[] args) { MagazineData magazineData = new MagazineData(); Observer customerA = new Customer("A"); Observer customerB = new Customer("B"); Observer customerC = new Customer("C"); magazineData.registerObserver(customerA); magazineData.registerObserver(customerB); magazineData.registerObserver(customerC); magazineData.setInfomation(5, 20); }
推模型:被觀察者主動向觀察者推送自身的信息,能夠是所有信息或者是部分信息。3d
拉模型:被觀察者經過把自身的引用傳遞給觀察者,須要觀察者自行經過該引用來獲取相關的信息。code
好比咱們有兩個對象,一個對象依賴於另外一個對象的變化而變化,此時咱們能夠將這兩個對象抽象出來,作成接口,利用觀察者模式來進行解耦,又或者,當一個對象發生變化的時候,須要通知別的對象來作出改變,但又不知道這樣的對象有多少個,此時利用觀察者模式很是合適。server
參考例子對象