觀察者模式:定義了對象之間的一對多依賴,這樣一來,當一個對象狀態改變時,他的全部依賴者都會收到通知並自動更新。java
觀察者模式涉及的角色
主題(Subject):一對多中的一,持有數據,當數據更新時,通知已註冊的觀察者ide
觀察者(Observer):一對多中的多,接收主題數據作出響應this
一位媽媽(主題)有兩個孩子,取名爲小愛和小冰(觀察者)。一天小愛和小冰都去找她們的朋友玩,當到了吃飯的時間,媽媽總會打電話通知她們回來吃飯(孩子默認在媽媽那註冊爲觀察者registerObserver),但中途小冰打電話和媽媽說:「不回來吃飯了,和朋友吃」(取消觀察者這角色removeObserver)。因此最後,只有小冰收到媽媽的通知,並告訴她今天買了你喜歡吃的雞腿(notifyObserver)。spa
Person.java,Mother和Child都繼承這個類[這步和講述觀察者模式沒什麼關係]code
public class Person { private String name; public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Mother.javaserver
public class Mother extends Person implements Subject{ /** * 她要通知的孩子 */ private ArrayList<Observer> children = new ArrayList<>(); /** * 通知的內容 */ private String message; public Mother(String name) { super(name); } @Override public void registerObserver(Observer observer) { children.add(observer); } @Override public void removeObserver(Observer observer) { children.remove(observer); } @Override public void notifyObserver() { children.forEach(observer -> observer.message(message)); } public void sendMessage(String message) { this.message = message; // 通知她們 notifyObserver(); } }
Child.java對象
public class Child extends Person implements Observer{ public Child(String name) { super(name); } @Override public void message(String m) { System.out.println(getName() + "收到的消息:" + m); } }
Main.java繼承
public class Main { public static void main(String[] args) { Mother mother = new Mother("媽媽"); Child xiaoBing = new Child("小冰"); Child xiaoAi = new Child("小愛"); // 孩子都是親生的,吃飯時叫她們 mother.registerObserver(xiaoBing); mother.registerObserver(xiaoAi); mother.sendMessage("飯煮好了,回來吃飯,買了大家想吃的雞腿"); System.out.println("------------------分割線-----------------------"); // 小愛說不回來吃了,取消通知她 mother.removeObserver(xiaoAi); mother.sendMessage("飯煮好了,回來吃飯,買了大家想吃的雞腿"); } }
運行結果:接口
小冰收到的消息:飯煮好了,回來吃飯,買了大家想吃的雞腿 小愛收到的消息:飯煮好了,回來吃飯,買了大家想吃的雞腿 ------------------分割線----------------------- 小冰收到的消息:飯煮好了,回來吃飯,買了大家想吃的雞腿
優勢
主題與觀察者之間鬆耦合。有新類型的觀察者出現時,主題的代碼不須要修改。假如咱們有一個新的具體類須要當觀察者,咱們不須要爲了兼容新類型而修改主題的代碼,全部要作的就是在新的類裏實現此觀察者接口,而後註冊成觀察者便可。圖片
就比如如上面例子,若是國家不久的未來開放三胎政策,媽媽又生了個小娜,媽媽不須要修改自身的邏輯。若是孩子要回家吃飯就實現Observer接口,媽媽那registerObserver就OK。