python設計模式-觀察者
定義:
定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴的物件都會得到通知並被自動更新。
觀察者模式是物件的行為模式,又叫釋出-訂閱(pubish/subscribe)模式,模型-檢視(Model/View模式),源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。
角色:
抽象主題,具體主題(釋出者), 抽象觀察者,具體觀察者(訂閱者)
適用場景:
當一個抽象模型有兩個方面,其中一個方面依賴於另一個方面.將兩者封裝在獨立的物件中以使它們各自獨立的改變和複用
當一個物件的改變需要同時改變其他物件,而且不知道具體有多少物件以待改變
當一個物件必須通知其他物件,而又不知道其他物件是誰,即這些物件之間是解耦的
優點:
目標與觀察者之間的耦合最小
缺點:
多個觀察者之間互不知道對方的存在,因此一個觀察者對主題的修改可能造成錯誤的更新
好, 概念說完來實際場景,以我目前公司業務為背景,產品上線後經常會收到使用者反饋bug。那麼通常由運營同事收集bug-》開發修復bug-》測試驗證bug-》運維釋出新版本到線上
直接上程式碼:
class OBperson(): '抽象觀察者' def updata(self): pass class TestOB(OBperson): '具體觀察者' def updata(self): print('I am tester, Verification bug') class Devob(OBperson): '具體觀察者' def updata(self): print('i am developing , Fix bug') class Announcerob(OBperson): '具體觀察者' def updata(self): print('i am announcer, release new version') class OBperation(): '具體釋出者' def __init__(self): self.__observers = [] def collect_bug(self): print('Number of bugs collected : ') self.notifyObserver() def addOBserver(self, observer): self.__observers.append(observer) def removeOBserver(self, observer): self.__observers.remove(observer) def notifyObserver(self): for ob in self.__observers: ob.updata() if __name__ == '__main__': p = OBperation() p.addOBserver(Devob()) p.addOBserver(TestOB()) p.addOBserver(Announcerob()) p.collect_bug()
執行結果:
設計要點:
被觀察者至少需要有三個方法:新增監聽者, 移除監聽者, 通知OBserver的方法,觀察者至少要有一個方法:更新方法,更新當前內容,
並作出相應處理
推模型和拉模型:
觀察者模式根據其側重的功能還可以分為推模型和拉模型。
推模型:被觀察者物件向觀察者推送主題的詳細資訊,不管觀察者是否需要,推送的資訊通常是主題物件的全部或部分資料。一般這種模型的實現中,會把被觀察者物件中的全部或部分資訊通過 update 的引數傳遞給觀察者 [update(Object obj) ,通過 obj 引數傳遞]。
拉模型:被觀察者在通知觀察者的時候,只傳遞少量資訊。如果觀察者需要更具體的資訊,由觀察者主動到被觀察者物件中獲取,相當於是觀察者從被觀察者物件中拉資料。一般這種模型的實現中,會把被觀察者物件自身通過 update 方法傳遞給觀察者 [update(Observable observable ),通過 observable 引數傳遞 ],這樣在觀察者需要獲取資料的時候,就可以通過這個引用來獲取了。