Python版設計模式之監聽者模式

監聽模式

又名觀察者模式、發佈/訂閱模式、源-監聽器(Source/Listener)模式,模式的核心是:設計時要區分誰是被觀察者,誰是觀察者。被觀察者至少有三個方法,添加觀察者、刪除觀察者、監聽目標變化並通知觀察者;觀察者這至少包含一個方法,當接收到被觀察者的通知時,做出相應的處理(即在被觀察者的監聽中調用)。

模式框架

'''
觀察者模式
'''
class Observable(object):
    '''
    被監聽的對象,實現類需要具體增加被監聽的資源
    '''
    def __init__(self):
        self.__observers = []

    @property
    def observers(self):
        return self.__observers

    def has_observer(self):
        return False if not self.__observers else True

    def add_observer(self, observer):
        self.__observers.append(observer)

    def remove_observer(self, observer):
        self.__observers.remove(observer)

    def listener(self, obj=None):
        for observer in self.__observers:
            observer.update(self, obj)


class Observer(object):
    '''
    觀察者,當觀察的對象發生變化時,依據變化情況增加處理邏輯
    '''
    def update(self, observable, obj):
        pass

UML圖

clipboard.png

示例

'''
基於觀察者模式,實現一個簡單的消息隊列,當隊列中有消息時,將消息發送給監聽者
'''
class MyQueue(Observable):
    def __init__(self):
        super().__init__()
        self.__resource = []

    def has_message(self):
        return True if self.__resource else False

    def queue_size(self):
        return len(self.__resource)

    def add_resource(self, res):
        self.__resource.append(res)
        print("新消息進入,推送...")
        self.listener(obj=res)


class MySubOdd(Observer):
    def update(self, observable, obj):
        if isinstance(observable, MyQueue) and int(obj) % 2 != 0:
            print("I'm MySubOdd, Get Message {} from MyQueue.".format(obj))


class MySubEven(Observer):
    def update(self, observable, obj):
        if isinstance(observable, MyQueue) and int(obj) % 2 == 0:
            print("I'm MySubEven, Get Message {} from MyQueue.".format(obj))


if __name__ == "__main__":
    my_queue = MyQueue()        # 初始化一個隊列
    my_sub_odd = MySubOdd()     # 初始化奇數監聽者
    my_sub_even = MySubEven()   # 初始化偶數監聽者

    # 將兩個監聽者加入監聽隊列
    my_queue.add_observer(my_sub_odd)
    my_queue.add_observer(my_sub_even)

    # 添加資源進隊列
    my_queue.add_resource("1")
    my_queue.add_resource("3")

    my_queue.add_resource("2")
    my_queue.add_resource("4")
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章