Observer(观察者) — 对象行为型模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
适用场景
- 对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变。
- 一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,你不希望这些对象是紧密耦合的。
UML图
-
Subject(目标)
- 目标知道它的观察者。可以有任意多个观察者观察同一个目标。
- 提供注册和删除观察者对象的接口。
-
Observer(观察者)
- 为那些在目标发生改变时需要获得通知的对象定义一个更新接口。
-
ConcreteSubject(具体目标)
- 将有关状态存入各 ConcreteObserver 对象。
- 当它的状态发生改变时,向其各个观察者发出通知。
-
ConcreteObserver(具体观察者)
- 维护一个指向 ConcreteSubject 对象的引用。
- 存储有关状态,这个状态应与目标的状态保持一致。
- 实现 Observer 的更新接口,以使自身状态与目标的状态保持一致。
效果
- Observer 模式允许你独立地改变目标和观察者。
- 目标和观察者建的抽象耦合:一个目标所知道的仅仅是它有一系列观察者,但不知道是谁。
- 支持广播通信:不像通常的请求,目标发送的通知不需要指定它的接收者。通知被自动广播给所有已向该目标对象登记的对象。目标对象并不关心到底有多少对象对自己感兴趣,它唯一的责任就是通知它的各观察者。
实现
import abc
class E_commerce(object):
"""
电商基类,实现了注册,注销观察者,通知所有观察者方法
"""
def __init__(self):
self._observers = []
def add_observer(self, observer):
if observer not in self._observers:
self._observers.append(observer)
def delete_observer(self, observer):
if observer in self._observers:
self._observers.remove(observer)
else:
raise Exception('%s observer not be monitored' % observer)
def notify_all_observers(self, promotion):
for observer in self._observers:
observer.update(self, promotion)
class A_shop(E_commerce):
"""
A电商, 被观察对象
"""
def __init__(self):
super(A_shop, self).__init__()
self._promotion = [] # 促销活动列表
def __str__(self):
return 'A_电商'
@property
def promotion(self):
"""返回所有促销活动"""
return self._promotion
@promotion.setter
def promotion(self, promotion):
self._promotion.append(promotion) # 添加新的促销活动
self.notify_all_observers(promotion) # 把新促销活动信息发送给关注店铺的人(观察者)
class Observer(object):
"""
观察者抽象基类,实现了更新方法
"""
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def update(self, *args, **kwargs):
pass
class A_customer(Observer):
"""
A客户实现了update方法
"""
def update(self, e_commerce, promotion):
print('to a_customer: %s正在%s' % (e_commerce, promotion))
class B_customer(Observer):
"""
A客户实现了update方法
"""
def update(self, e_commerce, promotion):
print('to b_customer: %s正在%s' % (e_commerce, promotion))
client
if __name__ == '__main__':
a_customer = A_customer()
b_customer = B_customer()
a_shop = A_shop()
a_shop.add_observer(a_customer) # 注册
a_shop.add_observer(b_customer) # 注册
a_shop.promotion = '大减价'
a_shop.promotion = '清仓大处理'
a_shop.delete_observer(a_customer)
a_shop.promotion = '大出血'
"""output
to a_customer: A_电商正在大减价
to b_customer: A_电商正在大减价
to a_customer: A_电商正在清仓大处理
to b_customer: A_电商正在清仓大处理
to b_customer: A_电商正在大出血
"""