原文链接:https://www.cnblogs.com/-wenli/p/10967306.html
监听模式
我们希望在一个对象的状态改变时更新另一个对象,即类似MCV模式,当多个视图共用一组模型数据时,只要有一个视图进行了数据的修改,其他视图都可以进行更新。
上面的问题就是监听模式需要去解决的。怎么解决?
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都可以得到通知,并根据通知按需进行自动更新
状态改变后,所有的依赖对象都将得到通知(广播通知)
重点 —— 在被观察者类中,加入一个arrayList存放观察者,这里就涉及到一个挺有意思的问题,被观察者对不同的观察者发送推送消息是有顺序的。
应用场合:
- 拍卖竞价,出价后,通知各个竞拍者进行竞价
- 服务器作为被观察者,服务器状态变化后,通知发给各个客户端,各个客户端做相应的行为
设计一个被观察者,一组观察者。
被观察者需要有三个基本的方法:
- 添加观察者
- 删除观察者
- 监听目标变化并通知观察者
观察者至少要有一个方法:
- 接收到被观察者的通知后,做出相应的callback。
基本代码:
# -*- coding: utf-8 -*-
# 定义一个发布者/被观察者
class Publisher:
def __init__(self):
# 用于放置观察者
self.__observers = []
#TODO:检查观察者列表是否为空
def hasObserver(self):
return False if not self.__observers else True
#TODO:添加观察者
def addObserver(self,observer):
# 添加之前检查是否存在
if observer not in self.__observers:
self.__observers.append(observer)
else:
print("Failed to add:{}".format(observer))
#TODO:移除观察者
def removeObserver(self,observer):
try:
self.__observers.remove(observer)
except ValueError:
print("Failed to remove:{}".format(observer))
#TODO:发布消息
def notify(self):
for observer in self.__observer:
observer.update(self)
# 定义一个订阅者/观察者
class Observer:
def update(self,publiser):
pass
实例
from Observer import Publisher,Observer
class DefaultFormatter(Publisher):
def __init__(self,name):
super(DefaultFormatter, self).__init__()
self.name = name
self._data = 0
# TODO: 返回关于发布者名称和 _data值的信息
def __str__(self):
return "{}:{} has data = {}".format(type(self).__name__,self.name, self._data)
def data(self):
return self._data
def setData(self, value):
try:
self._data = int(value)
except ValueError as e:
print('Error:{}'.format(e))
else:
print('修改了')
self.notify()
class HexFormatter(Observer):
def update(self, publiser):
print("hex data = {}".format(hex(publiser.data())))
class BinaryFormatter(Observer):
def update(self, publiser):
print("Bin data = {}".format(bin(publiser.data())))
if __name__ == '__main__':
# 创建publisher和observer
default = DefaultFormatter("test")
hexFormatter = HexFormatter()
binFormatter = BinaryFormatter()
default.addObserver(hexFormatter)
default.addObserver(binFormatter)
# publisher状态更新
default.setData(1)
default.setData(10)
# 移除一个observer
default.removeObserver(hexFormatter)
default.setData(20)