1.白话栗子
市里新修了一个图书馆,现在招募一个图书管理员叫T,T知道图书馆里的图书更新和借阅等信息。现在有三个同学甲乙丙想去了解以后几个月的图书馆图书信息和借阅信息,于是它们去T那里注册登记。当图书馆图书更新后,T就给注册了的同学发送图书更新信息。三个月后,丙不需要知道图书更新信息了,于是就去T那儿注销了它的信息。所以,以后,只有甲乙会收到消息。几个月后,丁也去图书馆注册了信息,所以以后甲乙丁会收到图书更新信息。
2.原理
当我们遇到一个多对一
的依赖关系时,就可以用观察者模式。观察者模式有一个
被观察者(subject
)和多个
观察者(observer
)。被观察者提供注册
、删除
、通知
的功能,观察者提供数据更新
和展示
等功能。
上面栗子中,T就是一个被观察者,T提供了注册身份信息的功能、删除信息的功能和给甲乙丙丁发送通知的功能,而甲乙丙丁就是观察者,更新它们从T那个获取的信息。
3.好处
独立封装,互不影响:观察者和被观察者都是独自封装
好的,观察者之间并不会相互影响
热插拔:在软件运行中,可以动态
添加和删除观察者
4.Show in Code
class Subject(object):
def __init__(self):
self._observers = [] #观察者列表
#注册功能
def attach(self, observer):
if observer not in self._observers:
self._observers.append(observer)
#删除功能
def delete(self, observer):
try:
self._observers.remove(observer)
except ValueError:
pass
#通知功能
def notify(self, modifier=None):
for observer in self._observers:
if modifier != observer:
observer.update(self)
#被观察者数据来源
class Data(Subject):
def __init__(self, name=''):
Subject.__init__(self)
self.name = name
self._data = 0
@property
def data(self):
return self._data
@data.setter
def data(self, value):
self._data = value
self.notify()
#观察者
class Viewer:
def __init__(self, name=''):
self._name = name
def update(self, subject):
print('my name is ', self._name, 'and', subject.name, '***', subject.data)
if __name__ == '__main__':
data1 = Data('管理员T')
view1 = Viewer('甲')
data1.attach(view1)
view2 = Viewer('乙')
data1.attach(view2)
view3 = Viewer('丙')
data1.attach(view3)
print('data1初始值')
print(data1.data)
print('改变data1的值')
data1.data = 5
print('再次改变data1的值')
data1.data = 10
print('删除view3后')
data1.delete(view3)
data1.data = 90