• python模式设计代码之观察者模式


    1、观察者模式

    话题订阅模式。观察者模式有两个角色,分别是话题发布者和话题订阅者(即观察者)。发布者就是把消息发送给话题,观察者就是订阅这个话题从而得到最新的资讯。这个模式的作用就拿手机的消息推送来说,app身为观察者提前订阅好话题,一旦发布者把信息发送给话题,所有的观察者就会收到这个信息。
    在这里插入图片描述

    2、观察者模式简单代码

    定义发布者

    class Subject:
        def __init__(self):
            self._observers = []
    
        def attach(self, observer):
            self._observers.append(observer)
    
        def detach(self, observer):
            self._observers.remove(observer)
    
        def notify(self,message):
            for observer in self._observers:
                observer.update(self, message)
    

    定义观察者

    class Observer:
        def update(self, subject,message):
            pass
    
    class ConcreteObserverA(Observer):
        def update(self, subject,message):
            print("ConcreteObserverA: {message}")
    
    class ConcreteObserverB(Observer):
        def update(self, subject,message):
            print("ConcreteObserverB: {message}")
    

    使用观察者模式

    # 创建主题对象
    subject = Subject()
    
    # 创建观察者对象
    observer_a = ConcreteObserverA()
    observer_b = ConcreteObserverB()
    
    # 注册观察者到主题
    subject.attach(observer_a)
    subject.attach(observer_b)
    
    # 模拟主题状态改变并通知观察者
    subject.notify()
    
    # 输出:
    # ConcreteObserverA: Reacted to the event
    # ConcreteObserverB: Reacted to the event
    

    实际案例:和twisted联合运用

    from twisted.internet.protocol import ReconnectingClientFactory, Protocol
    from twisted.protocols.basic import LineReceiver
    from twisted.internet.endpoints import TCP4ClientEndpoint
    from twisted.internet import reactor
    class Subject:
        """定义发布者"""
        def __init__(self):
            self._observers = []
    
        def attach(self, observer):
            self._observers.append(observer)
    
        def detach(self, observer):
            self._observers.remove(observer)
    
        def notify(self,message):
            for observer in self._observers:
                observer.update(self, message)
                
     class Observer:
         """定义观察者"""
        def update(self, subject,message):
            pass
    
    class ConcreteObserverA(Observer):
        """观察者A"""
        def update(self, subject,message):
            print(f"观察到{message}")
    
    class ConcreteObserverLog(Observer):
        def update(self, subject,message):
            print(f"{message}正在写入日志文件")
                
    class  ClientProtocol(LineReceiver): 
        "客户端数据接受及处理模块"  
        #根据帧尾巴解决粘包 
        delimiter  = b'\x5F\x5F\x65\x6E\x64\x5F\x5F'
    
        def __init__(self):
            #开一个线程,可以不断接受客户端用户的输入、点击动作之类的,而不影响主线程
            reactor.callInThread(self.user_input)
            #初始化发布者,赋值给self.subject,用来发布信息用self.subject.notify(message)
            self.subject = Subject()
            #初始化观察者a和观察者b
            observer_a = ConcreteObserverA()
            observer_b = ConcreteObserverLog()
            #观察者a和观察者b订阅self.subject发布的话题,使用attach订阅
            self.subject.attach(observer_a)
            sself.ubject.attach(observer_b)
        def connectionLost(self, reason):
            print("Disconnected from the server!") 
    
        def lineReceived(self, line):
            #不断地接受服务端的信息;websocket、tcp协议等长连接会一直收到服务器信息
            #这里通过发布者subject.notify,不断地把新消息发布到话题上,这样每次有新消息
            #观察者的信息就会更新,并对应动作,比如写入日志文件、打印到终端
            self.subject.notify(line)
         def user_input(self):
             while True:
                 the_input = input("请输入命令(输入'exit'退出): ")
                 if command_key == 'EXIT':
                    print("正在退出...")
                    self.transport.loseConnection()
                    break
     
     class ClientFactory(ReconnectingClientFactory):
        """Tcp 连接模块"""
    
        def startedConnecting(self, connector):
            print('Started to connect.')
    
        def buildProtocol(self, addr):
            print('Connected.')
            return ClientProtocol()
    
        def clientConnectionLost(self, connector, reason):
            print('Lost connection.  Reason:', reason)
    
        def clientConnectionFailed(self, connector, reason):
            print('Connection failed. Reason:', reason)
            ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)   
    #运行起来twisted 
    ClientInput = ClientFactory()
    sender_endpoint = TCP4ClientEndpoint(reactor, "192.168.1.100", 9981)
    sender_endpoint.connect(ClientInput)
    reactor.run()       
    
    
  • 相关阅读:
    PS一些小知识
    ArrayList源码解析
    UIAutomatorViewer排查问题
    从零开始编写一个 Python 异步 ASGI WEB 框架
    《动手学深度学习 Pytorch版》 9.6 编码器-解码器架构
    阿里架构师深度学习java虚拟机心得PDF、不愧是进了阿里的大牛
    《C++ Primer》导学系列:第 3 章 - 字符串、向量和数组
    Linux Shell 脚本语法以及常用命令
    java毕业设计项目源代码S2SH高校宿舍管理系统|寝室管理
    MongoDB ObjectId() 是如何实现的 “千万级” 分布式唯一 ID?
  • 原文地址:https://blog.csdn.net/li2642530979/article/details/141072753