它定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新。
角色:
一、抽象主題(Subject):
它把全部觀察者對象的引用保存到一個彙集裏,每一個主題均可以有任何數量的觀察者。抽象主題提供一個接口,能夠增長和刪除觀察者對象。
二、具體主題(Concrete Subject):
將有關狀態存入具體觀察者對象;在具體主題內部狀態改變時,給全部登記過的觀察者發出通知。
三、抽象觀察者(Observer):
爲全部的具體觀察者定義一個接口,在獲得主題通知時更新本身。
四、具體觀察者(Concrete Observer):
實現抽象觀察者角色所要求的更新接口,以便使自己的狀態與主題狀態協調
過程
實現觀察者模式有不少形式,比較直觀的一種是使用一種「註冊—通知—撤銷註冊」的形式。
觀察者
(Observer)將本身註冊到被觀察對象(Subject)中,被觀察對象將觀察者存放在一個容器(Container)裏。
被觀察
被觀察對象發生了某種變化(如圖中的SomeChange),從容器中獲得全部註冊過的觀察者,將變化通知觀察者。
撤銷觀察
觀察者告訴被觀察者要撤銷觀察,被觀察者從容器中將觀察者去除。
app
舔狗想知道女神都在幹些什麼,那麼首先舔狗得觀察女神,而後女神得容許接受舔狗的觀察。
class Observer(abc.ABC): def __init__(self, subject): self.subject = subject # 目標對象 @abc.abstractmethod def update(self): pass class TIMDog(Observer): def __init__(self,subject): super().__init__(subject) def update(self): print("舔狗看到女神正在:") print(self.subject.word) class Woman: def __init__(self): self.observer = [] @property def word(self): if hasattr(self, '_word'): return self._word return None @word.setter def word(self, value): self._word = value self.message() def attach(self, observer: Observer): # 依賴倒置原則 self.observer.append(observer) def remove(self, observer): self.observer.remove(observer) def message(self): for obs in self.observer: obs.update() w = Woman() t = TIMDog(w) # 我要觀察W w.attach(t) # w 受權 容許 t 觀察 w.word = "自摸 幺雞"
什麼是可調用對象?函數
一個類只要實現了__call__魔術方法, 就表示當前對象實例可用函數那麼調用。spa
可調用對象有:函數 與實現__call__的類對象實例code
class Obj: def __call__(self): pass o = Obj() # 可調用對象 也就是說 對象實例能夠用方法那樣 o() 等價於 o.__call__()
採用__call__改版後的觀察者模式server
import abc from typing import List ''' 舔狗想知道女神都在幹些什麼,那麼首先舔狗得觀察女神,而後女神得容許接受舔狗的觀察。 ''' class Observer(abc.ABC): def __init__(self, subject): self.subject = subject # 目標對象 @abc.abstractmethod def __call__(self): pass class TIMDog(Observer): def __init__(self,subject): super().__init__(subject) def __call__(self): print("舔狗看到女神正在:") print(self.subject.word) class Woman: def __init__(self): self.observer = [] @property def word(self): if hasattr(self, '_word'): return self._word return None @word.setter def word(self, value): self._word = value self.message() def attach(self, observer: Observer): self.observer.append(observer) def remove(self, observer): self.observer.remove(observer) def message(self): for obs in self.observer: obs() w = Woman() t = TIMDog(w) # 我要觀察W w.attach(t) # w 受權 容許 t 觀察 w.word = "自摸 幺雞"