Python之觀察者模式(發布訂閱)


一、介紹

觀察者模式是一種對象行為模式。它定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新,這種模式有時又稱作發布-訂閱模式、模型-視圖模式。在觀察者模式中,主體是通知的發布者,它發出通知時並不需要知道誰是它的觀察者,可以有任意數目的觀察者訂閱並接收通知。觀察者模式不僅被廣泛應用於軟件界面元素之間的交互,在業務對象之間的交互、權限管理等方面也有廣泛的應用。

例如,用戶界面可以作為一個觀察者,業務數據是被觀察者,用戶界面觀察業務數據的變化,發現數據變化后,就顯示在界面上。

 

二、觀察者模式

觀察者模式的結構:

  1. 抽象主題(AbstractSubject):也叫抽象目標類,它提供了一個用於保存觀察者對象的聚集類和增加、刪除觀察者對象的方法,以及通知所有觀察者的抽象方法
  2. 具體主題(Subject):也叫具體目標類,它實現抽象目標中的通知方法,當具體主題的內部狀態發生改變時,通知所有注冊過的觀察者對象。
  3. 抽象觀察者(AbstractObserver):它是一個抽象類或接口,它包含了一個更新自己的抽象方法,當接到具體主題的更改通知時被調用。
  4. 具體觀察者(Observer):實現抽象觀察者中定義的抽象方法,以便在得到目標的更改通知時更新自身的狀態。

import abc


class AbstractSubject(metaclass=abc.ABCMeta):
    """
    抽象主題(抽象目標類):
        定義增加、刪除觀察者的方法
        通知觀察者的抽象方法
    """

    def __init__(self):
        self.observers = []

    def add(self, observer):
        if observer not in self.observers:
            self.observers.append(observer)
        else:
            print("%s observer is exist, add failed" % observer)

    def remove(self, observer):
        if observer in self.observers:
            self.observers.remove(observer)
        else:
            print("%s observer is not exist, remove failed" % observer)

    @abc.abstractmethod
    def notify(self):
        pass


class Subject(AbstractSubject):
    """具體主題(具體目標類)"""

    def __init__(self, name):
        super().__init__()
        self.name = name
        self._data = None

    @property
    def data(self):
        return self._data

    @data.setter
    def data(self, new_data):
        """當數據更新時,去通知觀察者"""
        self._data = new_data
        self.notify()

    def notify(self):
        """通知觀察者的具體方法"""
        for obs in self.observers:
            obs.notify(self._data)


class AbstractObserver(metaclass=abc.ABCMeta):
    """抽象觀察者"""

    @abc.abstractmethod
    def notify(self, data, *args, **kwargs):
        pass


class Observer1(AbstractObserver):
    """具體觀察者-1"""

    def notify(self, data, *args, **kwargs):
        print("發布的消息是:%s" % data)


class Observer2(AbstractObserver):
    """具體觀察者-2"""

    def notify(self, data, *args, **kwargs):
        print("發布的消息是:%s" % data)


# 具體主題(消息發布者)
sub = Subject("ming")

# 具體觀察者
obs1 = Observer1()
obs2 = Observer2()

# 添加觀察者
sub.add(obs1)
sub.add(obs2)

# 發布消息后,觀察者得到消息
sub.data = "號外號外!"

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM