Observer(观察者) — 对象行为型模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
适用场景
- 对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变。
- 一个对象必须通知其他对象,而它又不能假定其他对象是谁。换言之,你不希望这些对象是紧密耦合的。
UML图
-
Subject(目标)
- 目标知道它的观察者。可以有任意多个观察者观察同一个目标。
- 提供注册和删除观察者对象的接口。
-
Observer(观察者)
- 为那些在目标发生改变时需要获得通知的对象定义一个更新接口。
-
ConcreteSubject(具体目标)
- 将有关状态存入各 ConcreteObserver 对象。
- 当它的状态发生改变时,向其各个观察者发出通知。
-
ConcreteObserver(具体观察者)
- 维护一个指向 ConcreteSubject 对象的引用。
- 存储有关状态,这个状态应与目标的状态保持一致。
- 实现 Observer 的更新接口,以使自身状态与目标的状态保持一致。
效果
- Observer 模式允许你独立地改变目标和观察者。
- 目标和观察者建的抽象耦合:一个目标所知道的仅仅是它有一系列观察者,但不知道是谁。
- 支持广播通信:不像通常的请求,目标发送的通知不需要指定它的接收者。通知被自动广播给所有已向该目标对象登记的对象。目标对象并不关心到底有多少对象对自己感兴趣,它唯一的责任就是通知它的各观察者。
实现
import abcclass 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_电商'@propertydef promotion(self):"""返回所有促销活动"""return self._promotion@promotion.setterdef promotion(self, promotion):self._promotion.append(promotion) # 添加新的促销活动self.notify_all_observers(promotion) # 把新促销活动信息发送给关注店铺的人(观察者)class Observer(object):"""观察者抽象基类,实现了更新方法"""__metaclass__ = abc.ABCMeta@abc.abstractmethoddef update(self, *args, **kwargs):passclass 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_电商正在大出血 """