监听者模式

定义

在对象间定义一种一对多的依赖关系,当这个对象状态发生改变时,所有依赖它的对象都会被通知并自动更新。

核心思想

监听模式又名观察者模式,顾名思义就是观察与被观察的关系。比如你在烧开水的时候看着它开没开,你就是观察者,水就是被观察者;再比如你在带小孩,你关注他是不是饿了,是不是渴了,是不是撒尿了,你就是观察者,小孩就是被观察者。

观察者模式是对象的行为模式,又叫发布/订阅(Publish/Subscribe)模式、模型/视图(Model/View)模式、源/监听器(Source/Listener)模式或从属者(Dependents)模式。当你看这些模式的时候,不要觉得陌生,它们就是监听模式。

监听模式的核心思想就是在被观察者与观察者之间建立一种自动触发的关系。

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-

"""监听模式示例代码"""

from abc import ABCMeta, abstractmethod


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


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

def add_observer(self, observer):
self.__obversers.append(observer)

def remove_observer(self, observer):
self.__obversers.remove(observer)

def notify(self, obj=0):
for o in self.__obversers:
o.update(self, obj)


class WaterHeat(Observable):
def __init__(self):
super().__init__()
self.__temperature = 25

def get_temperature(self):
return self.__temperature

def set_temperature(self, temperature):
self.__temperature = temperature
print(f"当前的温度是: {self.__temperature}'C")
self.notify()


class WashingMode(Observer):
def update(self, observable, object):
temperature = observable.get_temperature()
if isinstance(observable, WaterHeat) and temperature >= 50 and temperature < 70:
print(f"水已烧好!温度正好,可以来洗澡了~")


class DrinkMode(Observer):
def update(self, observable, object):
temperature = observable.get_temperature()
if isinstance(observable, WaterHeat) and temperature >= 70:
print(f"水已烧好!可以来饮用了~")


if __name__ == "__main__":
heat_water = WaterHeat()
washing_obverser = WashingMode()
driking_observer = DrinkMode()
heat_water.add_observer(washing_obverser)
heat_water.add_observer(driking_observer)
print("*" * 60)
heat_water.set_temperature(40)
print("*" * 60)
heat_water.set_temperature(60)
print("*" * 60)
heat_water.set_temperature(90)

输出如下:
************************************************************
当前的温度是: 40'C
************************************************************
当前的温度是: 60'C
水已烧好!温度正好,可以来洗澡了~
************************************************************
当前的温度是: 90'C
水已烧好!可以来饮用了~