什么是监听者模式?
有一个热水器,热水器有洗澡模式和饮用模式,当水温达到50度时,热水器发出提醒当前是洗澡模式,当水温达到100度时,热水器发出提醒当前是饮用模式。
热水器就是被监听者,两种模式为监听者。
定义
监听模式是一种一对多的关系,可以有任意个(一个或多个)观察者对象同时监听某一个对象。
监听的对象叫观察者(后面提到监听者,其实就指观察者,两者是相同的),被监听的对象叫被观察者(Observable,也叫主题,即 Subject)。
被观察者对象在状态或内容(数据)发生变化时,会通知所有观察者对象,使它们能够做出相应的变化(如自动更新自己的信息)
代码框架
from abc import ABCMeta, abstractmethod
# 引入 ABCMeta 和 abstractmethod 来定义抽象类和抽象方法
class Observer(metaclass=ABCMeta):
"""观察者的基类"""
@abstractmethod
def update(self, observable, object):
pass
class Observable:
"""被观察者的基类"""
def __init__(self):
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)
Observable 是被观察者的抽象类,Observer 是观察者的抽象类。
addObserver、removeObserver 分别用于添加和删除观察者,notifyObservers 用于内容或状态变化时通知所有的观察者。
因为Observable 的 notifyObservers 会调用 Observer 的 update 方法,所有观察者不需要关心被观察的对象什么时候会发生变化,只要有变化就会自动调用 update,所以只需要关注 update 实现就可
以了。
实现代码
class WaterHeater(Observable):
"""热水器:战胜寒冬的有力武器"""
def __init__(self):
super().__init__()
self.__temperature = 25
def getTemperature(self):
return self.__temperature
def setTemperature(self, temperature):
self.__temperature = temperatur
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("水已烧开!可以用来饮用了。")
设计要点
- 要明确谁是观察者,谁是被观察者。一般观察者与被观察者之间是一对多的关系,一个被观察者可以有多个监听对象。
- Observable 在发送广播的时候,不需要指定具体的 Observer
- 被观察者至少有三个方法:添加监听者,移除监听者,通知监听者的方法。观察者至少要有一个方法:更新方法