定义:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖的对象都会得到通知并被自动更新。
观察者模式是对象的行为模式,又叫发布-订阅(pubish/subscribe)模式,模型-视图(Model/View模式),源-监听器(Source/Listener)模式或从属者(Dependents)模式。
角色:
抽象主题,具体主题(发布者), 抽象观察者,具体观察者(订阅者)
适用场景:
当一个抽象模型有两个方面,其中一个方面依赖于另一个方面.将两者封装在独立的对象中以使它们各自独立的改变和复用
当一个对象的改变需要同时改变其他对象,而且不知道具体有多少对象以待改变
当一个对象必须通知其他对象,而又不知道其他对象是谁,即这些对象之间是解耦的
优点:
目标与观察者之间的耦合最小
缺点:
多个观察者之间互不知道对方的存在,因此一个观察者对主题的修改可能造成错误的更新
好, 概念说完来实际场景,以我目前公司业务为背景,产品上线后经常会收到用户反馈bug。那么通常由运营同事收集bug-》开发修复bug-》测试验证bug-》运维发布新版本到线上
直接上代码:
class OBperson(): '抽象观察者' def updata(self): pass class TestOB(OBperson): '具体观察者' def updata(self): print('I am tester, Verification bug') class Devob(OBperson): '具体观察者' def updata(self): print('i am developing , Fix bug') class Announcerob(OBperson): '具体观察者' def updata(self): print('i am announcer, release new version') class OBperation(): '具体发布者' def __init__(self): self.__observers = [] def collect_bug(self): print('Number of bugs collected : ') self.notifyObserver() def addOBserver(self, observer): self.__observers.append(observer) def removeOBserver(self, observer): self.__observers.remove(observer) def notifyObserver(self): for ob in self.__observers: ob.updata() if __name__ == '__main__': p = OBperation() p.addOBserver(Devob()) p.addOBserver(TestOB()) p.addOBserver(Announcerob()) p.collect_bug()
运行结果:
设计要点:
被观察者至少需要有三个方法:添加监听者, 移除监听者, 通知OBserver的方法,观察者至少要有一个方法:更新方法,更新当前内容,
并作出相应处理
推模型和拉模型:
观察者模式根据其侧重的功能还可以分为推模型和拉模型。
推模型:被观察者对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。一般这种模型的实现中,会把被观察者对象中的全部或部分信息通过 update 的参数传递给观察者 [update(Object obj) ,通过 obj 参数传递]。
拉模型:被观察者在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到被观察者对象中获取,相当于是观察者从被观察者对象中拉数据。一般这种模型的实现中,会把被观察者对象自身通过 update 方法传递给观察者 [update(Observable observable ),通过 observable 参数传递 ],这样在观察者需要获取数据的时候,就可以通过这个引用来获取了。