• 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()       
    
    
  • 相关阅读:
    前端面试题日常练-day54 【面试题】
    libcurl库
    vscode ssh远程连接服务器的重置以及openssh
    码农必备?清华大学开源了一款写代码神器。。。
    ARM32开发--存储器介绍
    中台框架模块开发实践-用 Admin.Core 代码生成器生成通用代码生成器的模块代码
    Java基础:Java数据类型
    【Linux】进程理解
    二叉树的前序遍历
    工作分配问题——算法设计与分析(C实现)
  • 原文地址:https://blog.csdn.net/li2642530979/article/details/141072753