設計模式(python實現):觀察者模式

小丁喵發表於2019-02-16

1.白話栗子

市裡新修了一個圖書館,現在招募一個圖書管理員叫T,T知道圖書館裡的圖書更新和借閱等資訊。現在有三個同學甲乙丙想去了解以後幾個月的圖書館圖書資訊和借閱資訊,於是它們去T那裡註冊登記。當圖書館圖書更新後,T就給註冊了的同學傳送圖書更新資訊。三個月後,丙不需要知道圖書更新資訊了,於是就去T那兒登出了它的資訊。所以,以後,只有甲乙會收到訊息。幾個月後,丁也去圖書館註冊了資訊,所以以後甲乙丁會收到圖書更新資訊。

2.原理

當我們遇到一個多對一的依賴關係時,就可以用觀察者模式。觀察者模式有一個被觀察者(subject)和多個觀察者(observer)。被觀察者提供註冊刪除通知的功能,觀察者提供資料更新展示等功能。
上面栗子中,T就是一個被觀察者,T提供了註冊身份資訊的功能、刪除資訊的功能和給甲乙丙丁傳送通知的功能,而甲乙丙丁就是觀察者,更新它們從T那個獲取的資訊。

3.好處

獨立封裝,互不影響:觀察者和被觀察者都是獨自封裝好的,觀察者之間並不會相互影響
熱插拔:在軟體執行中,可以動態新增和刪除觀察者

4.Show in Code

class Subject(object):
    def __init__(self):
        self._observers = [] #觀察者列表

    #註冊功能
    def attach(self, observer):
        if observer not in self._observers:
            self._observers.append(observer)

    #刪除功能
    def delete(self, observer):
        try:
            self._observers.remove(observer)
        except ValueError:
            pass

    #通知功能
    def notify(self, modifier=None):
        for observer in self._observers:
            if modifier != observer:
                observer.update(self)

#被觀察者資料來源
class Data(Subject):
    def __init__(self, name=``):
        Subject.__init__(self)
        self.name = name
        self._data = 0
    @property
    def data(self):
        return self._data

    @data.setter
    def data(self, value):
        self._data = value
        self.notify()

#觀察者
class Viewer:
    def __init__(self, name=``):
        self._name = name
    def update(self, subject):
        print(`my name is `, self._name, `and`, subject.name, `***`, subject.data)

if __name__ == `__main__`:
    data1 = Data(`管理員T`)
    view1 = Viewer(`甲`)
    data1.attach(view1)
    view2 = Viewer(`乙`)
    data1.attach(view2)
    view3 = Viewer(`丙`)
    data1.attach(view3)

    print(`data1初始值`)
    print(data1.data)
    print(`改變data1的值`)
    data1.data = 5
    print(`再次改變data1的值`)
    data1.data = 10

    print(`刪除view3後`)
    data1.delete(view3)
    data1.data = 90
    
    

相關文章