Design Patterns——<一>监听模式

一、什么是监听模式?

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

监听模式又名观察者模式,是一种一对多的关系,被观察者(Observable,也称subject)对象在状态或内容发生变化时,会通知所有的观察者(observer)对象,使他们能够做出相应的变化。

观察者模式是对象的行为模式,又叫发布/订阅(Publish/Subscribe)模式、模型/视图(Model/View)模式、源/监听器(Source/Listener)模式或从属者(Dependents)模式。监听模式的核心思想就是在被观察者与观察者之间建立一种自动触发的关系。

二、代码框架

from abc import ABCMeta, abstractmethod     # 引入ABCmeta和abstractmethod来定义抽象类和抽象方法。

class Observer(metaclass=ABCMeta):
    '''观察者的基类'''
    @abstractmethod
    def update(self, observable, object):
        pass

class Observable:
    '''被观察者的基类'''
    def __init__(self) -> None:
        self._observers = []
        
    def addObserver(self, observer):
        self._observers.append(observer)
        
    def removeObserver(self, observer):
        self._observers.remove(observer)
        
    def notifyObservers(self, object=0):
        for o in self._observers:
            o.update(self, object)

在这里插入图片描述

三、代码示例


代码示例1.0
'''
@time: 2023/5/4 11:20
@autor: zyh
@file: observer.py
'''

from abc import ABCMeta, abstractmethod     # 引入ABCmeta和abstractmethod来定义抽象类和抽象方法。

class WaterHeater:
    '''热水器'''
    def __init__(self) -> None:
        self._observers = []
        self._temperature = 25
    
    def getTemperature(self):
        return self._temperature
    
    def setTemperature(self, temperature):
        self._temperature = temperature
        print("当前温度是:" + str(self._temperature) + "°C")
        self.notifies()
        
    def addObserver(self, observer):
        self._observers.append(observer)
        
    def notifies(self):
        for o in self._observers:
            o.update(self)
    
class WashingMode(Observer):
    '''洗澡模式'''
    
    def update(self, waterHeater):
        if waterHeater.getTemperature() >= 50 and waterHeater.getTemperature() <=70:
            print("水已烧好!温度正好,可以用来洗澡了。")
            
class DrinkingMode(Observer):
    '''饮用模式'''
    
    def update(self, waterHeater):
        if waterHeater.getTemperature() == 100:
            print("水已烧开!可以用来饮用了。")
            
def testWaterHeater():
    heater = WaterHeater()
    washingObser = WashingMode()
    drinkingObser = DrinkingMode()
    heater.addObserver(washingObser)
    heater.addObserver(drinkingObser)
    heater.setTemperature(40)
    heater.setTemperature(60)
    heater.setTemperature(100)
    
if __name__ == '__main__':
    testWaterHeater()

输出:

当前温度是:40°C
当前温度是:60°C
水已烧好!温度正好,可以用来洗澡了。
当前温度是:100°C
水已烧开!可以用来饮用了。

代码示例2.0(按照监听模式框架编写,框架见2)
from abc import ABCMeta, abstractmethod     # 引入ABCmeta和abstractmethod来定义抽象类和抽象方法。

class Observer(metaclass=ABCMeta):
    '''观察者的基类'''
    @abstractmethod
    def update(self, observable, object):
        pass

class Observable:
    '''被观察者的基类'''
    def __init__(self) -> None:
        self._observers = []
        
    def addObserver(self, observer):
        self._observers.append(observer)
        
    def removeObserver(self, observer):
        self._observers.remove(observer)
        
    def notifyObservers(self, object=0):
        for o in self._observers:
            o.update(self, object)
            
            
class WaterHeater(Observable):
    '''热水器'''
    def __init__(self) -> None:
        super().__init__()
        self._temperature = 25
    
    def getTemperature(self):
        return self._temperature
    
    def setTemperature(self, temperature):
        self._temperature = temperature
        print("当前温度是:" + str(self._temperature) + "°C")
        self.notifyObservers()
        
class WashingMode(Observer):
    '''洗澡模式'''
    
    def update(self, observable, object):
        if isinstance(observable, WaterHeater) and observable.getTemperature() >= 50 and observable.getTemperature() <= 70:
            print("水已烧好!温度正好,可以用来洗澡了。")
            
class DrinkingMode(Observer):
    '''饮用模式'''
    
    def update(self, observable, object):
        if isinstance(observable, WaterHeater) and observable.getTemperature() == 100:
            print("水已烧开!可以用来饮用了。")
            
def testWaterHeater():
    heater = WaterHeater()
    washingObser = WashingMode()
    drinkingObser = DrinkingMode()
    heater.addObserver(washingObser)
    heater.addObserver(drinkingObser)
    heater.setTemperature(40)
    heater.setTemperature(60)
    heater.setTemperature(100)
    
if __name__ == '__main__':
    testWaterHeater()

输出:

当前温度是:40°C
当前温度是:60°C
水已烧好!温度正好,可以用来洗澡了。
当前温度是:100°C
水已烧开!可以用来饮用了。

补充说明

1. 设计要点

  1. 明确观察者与被观察者。
  2. Observable在发送广播通知时,无须指定具体的Observer,Observer可以自己决定是否订阅Subject的通知。
  3. 被观察者至少需要三个方法:添加监听者、移除监听者、通知监听者;观察者至少有一个方法:更新方法。

2. 推模型&拉模型

监听模式根据侧重功能可分为推模型和拉模型。


推模型:
被观察者向监听者推送信息,不管监听者是否需要。一般在这种模型的实现中,会把被观察者对象中的全部或部分信息通过update参数传递给观察者。

如某APP的服务要在凌晨1:00开始维护,所有服务暂停1小时,此时就需要向所有APP客户端推送完成的通知消息“本APP于凌晨1:00-2:00维护,期间所有服务暂停!”
即不管用户想不想知道,也不管用户会不会在此期间使用,消息都需要被准确无误的送达。


拉模型:
被观察者在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到被观察者对象中获取,相当于观察者从被观察者对象中拉数据。一般在这种模型的实现中,会把被观察者对象自身通过update方法传递给观察者。

如某APP推出了新的版本,通知信息只会简单的列出版本号和下载地址,如果用户需要升级,还需要调用下载接口完成升级。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值