電影無間道很多人都看過,講的是關於黑社會與警局臥底的故事。
我們今天就聊一下無間道和麪向對象的觀察者模式到底有什麼關係。
//被觀察者
public interface Observable
{
void notifyEverybody(); //通知所有人
}
//曾志偉 扮演的 黑社會老大 韓琛
public class HanLaoda implements Observable {
ArrayList<Observer> observerList;//臥底們(除了梁朝偉還有很多臥底,比如陳朝偉、張朝偉)
public void notifyEverybody()
{
for (Observer item : observerList) {
item.reportWangSir();
}
}
//韓老大爲了擴充勢力,只管招小弟進來,但他不知道招進來的是臥底
public void addObserver(Observer observer)
{
observerList.add(observer);
}
//做違法事情
public void doWeifa()
{
//臥底們一旦發現韓老大要做違法事情,就開始祕密通知警方
notifyEverybody();
}
}
//觀察者
public interface Observer
{
//臥底 一旦發現有違法交易,立馬做出行動。報告給 黃秋生扮演的 王Sir。
void reportWangSir();
}
//梁朝偉 扮演的 樑永仁 是警局安插到黑社會的臥底
public class LiangChaowei implements Observer
{
public void reportWangSir()
{
//報告給王Sir
}
}
//陳朝偉
public class ChenChaowei implements Observer
{
public void reportWangSir()
{
//報告給王Sir
}
}
//張朝偉
public class ZhangChaowei implements Observer
{
public void reportWangSir()
{
//報告給王Sir
}
}
public class Client
{
public static void main()
{
HanLaoda han = new HanLaoda();
//韓老大爲了擴充勢力,只管招小弟進來,但他不知道招進來的是臥底
han.addObserver(new LiangChaowei());
han.addObserver(new ChenChaowei());
han.addObserver(new ZhangChaowei());
//做違法事情
han.doWeifa();
}
}
那觀察者模式在什麼情況下使用呢?
觀察者可以實現消息的廣播,一個消息可以觸發多個事件,這是觀察者模式非常重要的功能。
使用觀察者模式也有個重點問題要解決:
廣播鏈的問題
如果你做過數據庫的觸發器,你就應該知道有一個觸發器鏈的問題,比如表 A 上寫了一個觸發器,
內容是一個字段更新後更新表 B 的一條數據,而表 B 上也有個觸發器,要更新表 C,表 C 也有觸發器…,完蛋了,
這個數據庫基本上就毀掉了!我們的觀察者模式也是一樣的問題,一個觀察者可以有雙重身份,即使觀察者,
也是被觀察者,這沒什麼問題呀,但是鏈一旦建立,這個邏輯就比較複雜,可維護性非常差,根據經驗建議,
在一個觀察者模式中多出現一個對象既是觀察者也是被觀察者,也就是說消息多轉發一次(傳遞兩次),這還是比較好控制的。