02 设计模式之监听者模式

设计模式之监听者模式

1. 场景模拟

  • 监控温度,当温度到达一定程度时,会及时通知发出警告
  • 洗澡模式,饮用模式是监听者,热水器是被监听对象,热水器温度发生变化,监听者可以做出相应的判断
# 引入 定义抽象类和抽象方法
from abc import ABCMeta, abstractclassmethod
class WaterHeater:
    """热水器"""
    def __init__(self):
        self.__observers = []         # 监听者
        self.__temperature = 25

    def getTemperature(self):
        return self.__temperature

    def setTemperature(self, temperature):
        self.__temperature = temperature
        print("当前温度:" + str(self.__temperature) + "℃")
        self.notifies()

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

    def notifies(self):               # 通知
        for o in self.__observers:    # 两个实例化对象在里面,分别调用自身的update方法,然后比较温度
            o.update(self)

class Observer(metaclass=ABCMeta):
    """洗澡模式和饮用模式的父类"""

    @abstractclassmethod
    def update(self, waterHeater):
        pass

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()
    print(washingObser)
    drinkingObser = DrinkingMode()
    print(drinkingObser)
    # 添加监听者
    heater.addObserver(washingObser)
    heater.addObserver(drinkingObser)
    # 设置温度
    heater.setTemperature(40)
    heater.setTemperature(60)
    # heater.setTemperature(100)

testWaterHeater()

2. 监听模式-代码框架

  • Obsevervable是被观察者的抽象类,Observer是观察者的抽象类。addObserver,removeObserver用于添加和删除观察者,notifyObsever用于内容或状态变化时通知所有的观察者,因为Obsevervable的notifyObsever会调用 Observer的update方法,所有的观察者不需要关心对象什么时候会发生变化,只要有变化就会自动调用update,所以只需要关注update就好。
    02 设计模式之监听者模式
from abc import ABCMeta, abstractclassmethod

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

class Observable:
    """被观察者基类"""
    def __init__(self):
        self.__observer = []

    def addObserver(self, observer):
        self.__observer.append(observer)

    def removeObserver(self, observer):
        self.__observer.remove(observer)

    def notifyObservers(self, object=0):
        for o in self.__observer:
            o.update(self, object)

3. 框架改进后代码

from abc import ABCMeta, abstractclassmethod

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

class Observable:
    """被观察者基类"""
    def __init__(self):
        self.__observer = []

    def addObserver(self, observer):
        self.__observer.append(observer)

    def removeObserver(self, observer):
        self.__observer.remove(observer)

    def notifyObservers(self, object=0):
        for o in self.__observer:
            o.update(self, object)


class WaterHeater(Observable):
    """热水器"""
    def __init__(self):
        super().__init__()
        self.__temperature = 25

    def getTemperature(self):
        return self.__temperature

    def setTemperature(self, temperature):
        self.__temperature = temperature
        print("当前温度:" + str(self.__temperature) + "℃")
        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)

testWaterHeater()

自己对监督者模式的疑问:在实现update时,不知道waterHeater/obsevrvable为什么就是被监督者的实例化对象?

02 设计模式之监听者模式

上一篇:第一章 绪论


下一篇:Pytest + allure 环境安装