【設計模式】-09觀察者模式
1.什麼是觀察者模式?
定義:在物件之間定義了一對多的依賴,這樣一來,當一個物件改變狀態,依賴它的物件會收到通知並自動更新.
舉個栗子: 張三和李四準備上演一場搶劫銀行的行動,張三負責搶劫,李四負責放哨,他們兩約定,如果李四這邊看到警察來就立即通知張三,張三收到通知後立馬逃跑...在上面的例子中,張三的角色其實就是觀察者,李四是被觀察者.張三觀察李四這邊的狀態,如果李四這邊的狀態發生改變(一切正常->情況不妙),張三就立即做出行動或反饋.現實中類似的還有訊息的訂閱和接收,比如微信公眾號,其模式其實也是觀察者模式.
2.為什麼要使用觀察者模式?
觀察者模式可以降低系統耦合度,觀察者和主體(被觀察者)完美分離,另外主體的變化可以通知到所有匹配過的觀察者,所有依賴於主體的物件都得到通知並自動重新整理。
3.實現
先來看一下觀察者模式的結構圖:
觀察者模式主要由觀察者(Observer),主體(Subject)構成,再具體一點就是由抽象觀察者(observer),抽象主體(subject),觀察者實現類(concreteObserver),主體實現類(concreteSuject)構成,為了讓程式碼具有更高的可擴充套件性,你還可以把主體寫成抽象類,我這了為了演示就不寫的太複雜了,感興趣的可以看看百度百科提供的觀察者模式-javaDemo,那段程式碼寫的很精彩,值得一讀.
Subject:
主體,存放所有觀察者物件,存放自身狀態,以及新增/移除觀察者的方法,通知所有觀察者的方法
/** * 被觀察者物件 */ public class Subject { private List<Observer> observers = new ArrayList<>(); private Integer state; public void attach(Observer observer) { observers.add(observer); } public void remove(Observer observer) { observers.remove(observer); } private void notifyALLObserver() { for (Observer observer : observers) { observer.update(); } } public Integer getState() { return state; } public void setState(Integer state) { this.state = state; this.notifyALLObserver(); } }
observer:
觀察者物件,提供了update方法,以供在收到通知時及時作出反應.
/**
* 觀察者物件
*/
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
下面我以一個具體的例子來模擬實現觀察者模式. 現在有一對情侶,主體是丈母孃,只有在丈母孃狀態發生改變時(???)情侶才能作出具體的反饋,比如丈母孃的狀態由1變為了2(可以理解為生氣變成了高興),這個時候男生看到後會立刻去打遊戲,女生看到後則會去購物,程式碼模擬實現一下:
public class BoyObserver extends Observer {
/**
* 被構造時即被新增至觀察者列表裡
*/
public BoyObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("狀態改變了,狀態值變為了:" + subject.getState() + " 我要去打遊戲了....");
}
}
public class GirlObserver extends Observer {
/**
* 被構造時即被新增至觀察者列表裡
*/
public GirlObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("狀態改變了,狀態值變為了:" + subject.getState() +" 我要去購物了....");
}
}
/**
* 測試客戶端
*/
public class Client {
public static void main(String[] args) {
Subject subject = new Subject();
Observer girlObserver = new GirlObserver(subject);
Observer boyObserver = new BoyObserver(subject);
System.out.println("==========第一次===========>");
subject.setState(1);
System.out.println("==========第二次===========>");
subject.setState(2);
System.out.println("==========第三次===========>");
subject.remove(boyObserver);
subject.setState(3);
}
}
執行一下測試類可以看到控制檯輸出:
第一次當主體狀態變為1時,男孩和女孩都收到了通知,於是兩人都去幹自己喜歡的事了,第二次也一樣,第三次時,丈母孃不高興讓男孩打遊戲了,覺得這樣沒出息,於是把他從列表裡踢出去了,然後他就收不到通知了...
以上便是觀察者模式的簡單實現,如果想要提高程式碼的可擴充套件性,可以把主體寫得更抽象,運用泛型和反射,讓程式碼的擴充套件性爆棚.