设计模式之监听者模式
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就好。
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为什么就是被监督者的实例化对象?