• 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 = "号外号外!"
  • 相关阅读:
    Python 多核 多线程 调度
    mysql-select for update
    Python logging模块
    TCP/IP和HTTP协议与Socket的区别联系
    DNS+CDN
    wget命令
    Cannot find module 'webpack-cli/bin/config-yargs
    TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'
    js 创建私有变量
    报错集锦及解决方案
  • 原文地址:https://www.cnblogs.com/Zzbj/p/15779727.html
Copyright © 2020-2023  润新知