標籤:觀察者模式 表示 water merge 臨時 員工 多少 通訊 pytho
說明:
存在這樣的一種情況:公司領導再開例會那天臨時有事,他讓秘書給所有會上員工群發了一封郵件,通知大家會議取消,員工們收到郵件之後得知會議取消便繼續回到各自崗位開始工作。這其中就包含了一種隱含地思想就是:領導與員工們之間的“一對多的通知依賴關係”。即一個對象的狀態或行為的變化將導致其他對象的狀態或行為也發生改變,它們之間將產生聯動。
觀察者模式:
定義對象之間的一種一對多依賴關係,使得每當一個對象狀態發生改變時,其相關依賴對象都得到通知並被自動更新。發生改變的對象稱為觀察目標,被通知的對象稱為觀察者 。一個觀察目標可以對應多個觀察者
觀察者模式的結構
觀察者模式包含以下4個角色: Subject(目標) ConcreteSubject(具體目標) Observer(觀察者) ConcreteObserver(具體觀察者)
執行個體:
"""在門面模式中,我們提到過火警通報器。在當時,我們關注的是通過封裝減少代碼重複。而今天,我們將從商務程序的實現角度,來再次實現該火警通報器。"""class AlarmSensor: def run(self): print("Alarm Ring...")class WaterSprinker: def run(self): print("Spray Water...")class EmergencyDialer: def run(self): print("Dial 119...")"""以上是門面模式中的三個感應器類的結構。
仔細分析業務,通報器、洒水器、撥號器都是“觀察”煙霧感應器的情況來做反應的。
因而,他們三個都是觀察者,而煙霧感應器則是被觀察對象了。
根據分析,將三個類提取共性,泛化出“觀察者”類,並構造被觀察者。觀察者如下:"""class Observer: def update(self): passclass AlarmSensor(Observer): def update(self,action): print("Alarm Got: %s" % action) self.runAlarm() def runAlarm(self): print("Alarm Ring...")class WaterSprinker(Observer): def update(self,action): print("Sprinker Got: %s" % action) self.runSprinker() def runSprinker(self): print("Spray Water...")class EmergencyDialer(Observer): def update(self,action): print("Dialer Got: %s"%action) self.runDialer() def runDialer(self): print("Dial 119...")"""觀察者中定義了update介面,如果被觀察者狀態比較多,或者每個具體的觀察者方法比較多,
可以通過update傳參數進行更豐富的控制。下面構造被觀察者。"""class Observed: observers=[] action="" def addObserver(self,observer): self.observers.append(observer) def notifyAll(self): for obs in self.observers: obs.update(self.action)class smokeSensor(Observed): def setAction(self,action): self.action=action def isFire(self): return True"""被觀察者中首先將觀察對象加入到觀察者數組中,若發生情況,則通過notifyAll通知各觀察者。業務代碼如下:"""if __name__=="__main__": alarm=AlarmSensor() sprinker=WaterSprinker() dialer=EmergencyDialer() smoke_sensor=smokeSensor() smoke_sensor.addObserver(alarm) smoke_sensor.addObserver(sprinker) smoke_sensor.addObserver(dialer) if smoke_sensor.isFire(): smoke_sensor.setAction("On Fire!") smoke_sensor.notifyAll()
列印結果:
Alarm Got: On Fire!
Alarm Ring...
Sprinker Got: On Fire!
Spray Water...
Dialer Got: On Fire!
Dial 119...
模式優點
可以實現展示層和資料邏輯層的分離 在觀察目標和觀察者之間建立一個抽象的耦合 支援廣播通訊,簡化了一對多系統設計的難度 符合開閉原則,增加新的具體觀察者無須修改原有系統代碼,在具體觀察者與觀察目標之間不存在關聯關係的情況下,增加新的觀察目標也很方便
模式缺點
將所有的觀察者都通知到會花費很多時間 如果存在循環相依性時可能導致系統崩潰 沒有相應的機制讓觀察者知道所觀察的目標對象是怎麼發生變化的,而只是知道觀察目標發生了變化
模式適用環境
一個抽象模型有兩個方面,其中一個方面依賴於另一個方面,將這兩個方面封裝在獨立的對象中使它們可以各自獨立地改變和複用 一個對象的改變將導致一個或多個其他對象發生改變,且並不知道具體有多少對象將發生改變,也不知道這些對象是誰 需要在系統中建立一個觸發鏈
python-觀察者模式