天天看點

用python實作軟體設計模式之觀察者模式

作者:搬磚搬知識

前言

觀察者模式,一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀态發生變化時,會通知所有觀察者對象,使他們能夠自動更新自己。

代碼

  class Observer:
    def __init__(self) -> None:
        pass

    def Update(self) -> None:
        pass

class Subject:
    def __init__(self) -> None:
        self.observers : Observer = []

    def Attach(self, observer : Observer):
        self.observers.append(observer)
    
    def Detach(self, observer : Observer):
        self.observers.remove(observer)

    def Notify(self):
        for observer in self.observers:
            observer.Update()

class ConcreteSubject(Subject):
    def __init__(self) -> None:
        self.subject_state = ""
        super().__init__()
    
    @property
    def State(self):
        return self.subject_state
    
    @State.setter
    def State(self, subject_state):
        self.subject_state = subject_state

class ConcreteObserver1(Observer):
    def __init__(self, subject : Subject, name : str) -> None:
        self.subject = subject
        self.name = name

    def Update(self) -> None:
        print(f"觀察者{self.name}的新狀态是{self.subject.State}")
        self.Close_Light()

    def Close_Light(self):
        print("關燈")

class ConcreteObserver2(Observer):
    def __init__(self, subject : Subject, name : str) -> None:
        self.subject = subject
        self.name = name

    def Update(self) -> None:
        print(f"觀察者{self.name}的新狀态是{self.subject.State}")
        self.Close_TV()

    def Close_TV(self):
        print("關閉電視")

if __name__ == '__main__':
    s = ConcreteSubject()

    s.Attach(ConcreteObserver1(s, "X"))
    s.Attach(ConcreteObserver1(s, "Y"))
    s.Attach(ConcreteObserver2(s, "Z"))

    s.State = "ABC"
    s.Notify()           

運作結果:

用python實作軟體設計模式之觀察者模式

觀察者模式是通過Observer和Subject做父類,觀察者和被觀察者分别繼承它們,在觀察者類中維護被觀察者的實體,當觀察者類中的成員函數Notify被調用時,會周遊儲存的所有被觀察者實體,并調用其成員函數Update,達到通知的效果。

總結

什麼時候使用觀察者模式?1、當一個對象的改變需要同時改變其他對象的時候。2、一個抽象模型有兩個方面,其中一個方面依賴于另外一個方面,這時觀察者模式可以将這兩者封裝在獨立的對象中使它們各自獨立地改變和複用。

觀察者模式所做的工作其實就是在解除耦合,讓耦合的雙方都依賴于抽象,而不是依賴于具體。進而使得各自的變化都不會影響另一邊的變化。