你們上學時最懼怕的是什麼?是否是還被「班主任忽然出如今你後面」的恐懼支配着?時不時就得往窗口、門口望一望,老師沒過來就接着看小說,老師一過來固然得僞裝着寫做業。萬一咱們坐在靠近裏面的,不方便觀察,這時候咱們就只能讓坐在窗邊的王XX代勞了,王XX一看到老師來了,就喊一聲,這時咱們就明白怎麼回事了。java
定義:觀察者模式是軟件設計模式的一種。在此種模式中,一個目標物件管理全部相依於它的觀察者物件,而且在它自己的狀態改變時主動發出通知。這一般透過呼叫各觀察者所提供的方法來實現。此種模式一般被用來實現事件處理系統。
編程
注意點:設計模式
一、被觀察者管理觀察者bash
二、被觀察者狀態改變時主動發出通知markdown
在文章開頭的描述中,「王XX」看到老師來了就給其餘同窗發個信號,通知一下。「王XX」是被其餘同窗觀察,即爲被觀察者。其餘同窗則爲觀察者。ide
咱們定義了一個oop
Oberable接口,被觀察者接口,接口中定義了四個方法:測試
(1)teacherLeave() 用來發出消息,表示老師離開了spa
(2)teacherComeBack() 用來發出消息,表示老師回來了設計
(3)addNotificationStudent() 「王XX」同窗不可能通知全部同窗啊,須要通知的同窗須要事先跟「王XX」同窗說下。
(4)deleteNotificationStudent() "小丫"同窗,如今不須要通知了,經過這個方法讓「王XX」同窗再也不通知她
WangStudent類,表示「王XX」,保存須要通知的同窗名單,老師來了就通知這些同窗。
IObservor觀察者接口,有個方法用來接收「王XX」同窗發來的通知。
ObersorStuLi、ObersorStuZhang,李同窗、張同窗,具體的觀察類。
被觀察者接口
package com.design.observor;
public interface Observable {
public void teacherLeave();
public void teacherComeBack();
public void addNotificationStudent(IObservor observor);
public void deleteNotificationStudent(IObservor observor);
}複製代碼
被觀察者「王XX」同窗
package com.design.observor; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class WangStudent implements Observable { private int state; //須要通知的名單。管理觀察者,對應定義注意點1 private List<IObservor> obserbors; public WangStudent(){ obserbors = new ArrayList<>(); } //通知須要通知的同窗,老師走了 @Override public void teacherLeave() { state = 1; //被觀察者,主動發出通知,對應定義注意點2 Iterator<IObservor> iterator = obserbors.listIterator(); while (iterator.hasNext()){ iterator.next().updateOperation(state); } } //通知須要通知的同窗,老師來了 @Override public void teacherComeBack() { state = 0; Iterator<IObservor> iterator = obserbors.listIterator(); while (iterator.hasNext()){ iterator.next().updateOperation(state); } } //增長鬚要通知的同窗 @Override public void addNotificationStudent(IObservor observor) { obserbors.add(observor); } //刪除不須要通知的同窗 @Override public void deleteNotificationStudent(IObservor observor) { obserbors.remove(obserbors); } }複製代碼
觀察者接口
package com.design.observor;
public interface IObservor {
public void updateOperation(int state);
}複製代碼
觀察者同窗,「李同窗」、「張同窗」
package com.design.observor; public class ObservorStuLi implements IObservor{ @Override public void updateOperation(int state) { if(state == 0){ System.out.println("LiXX:老師來了,把小說收了,僞裝作題!!"); }else{ System.out.println("LiXX:老師走了,繼續看小說!!"); } } } 複製代碼
package com.design.observor; public class IObservorStuZhang implements IObservor { @Override public void updateOperation(int state) { if(state == 0){ System.out.println("ZhangXX:老師來了,中止跟XX調情,僞裝作題!!"); }else{ System.out.println("ZhangXX:老師走了,繼續跟XX調情!!"); } } }複製代碼
測試類
package com.design.observor;
public class TestMain {
public static void main(String[] args) {
Observable wangStu = new WangStudent();
IObservor liStu = new ObservorStuLi();
IObservor zhangStu = new IObservorStuZhang();
//李同窗、張同窗增長到須要通知的名單中
wangStu.addNotificationStudent(liStu);
wangStu.addNotificationStudent(zhangStu);
//老師來了
wangStu.teacherComeBack();
//老師走了
wangStu.teacherLeave();
}
}複製代碼
測試結果
好了,咱們完成了這個場景的編程,老師來了、走了,「王XX」同窗都通知了張同窗,還有李同窗,這時張同窗、李同窗就能夠放心玩他們想玩的了。
使用場景:當一個對象的改變須要同時改變其餘對象,且不知道具體有多少對象待改變時(咱們例子中須要通知的同窗是經過addNotificationStudent方法動態增長進去的),能夠考慮使用觀察者模式(來自《大話設計模式》)
(一)、優勢
一、觀察者和被觀察者是抽象耦合的。
(二)、缺點
一、若是在觀察者和觀察目標之間有循環依賴的話,觀察目標會觸發它們之間進行循環調用,致使死循環。(A通知B,B通知A,A通知B,B通知A ......)