什么是观察者模式
观察者(Observer)模式的定义: 指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。
对于观察者模式的理解,这里举个例子说明。
用软件发布测试为例,每次软件发布,都需要出告知各个同事(大佬),比如项目经理、项目负责人、部门老大、测试部门的老大、以及测试人员等等。
如果想让各位同事了解你的软件有没有发布测试,总不能麻烦各位大佬挨个隔一段时间问我们小小的软件开发吧!!!这样说,我就是那个被观察者,各位大佬就是观察者。
如何解决上面那个问题?那就是打电话(或者邮件),首先各位大佬想要了解软件是否发布,但是软件什么时候能把bug全部解决、发布,这个时间我自己都不知道,于是各位大佬就把自己的电话号码甩给你,说发布了立马打电话通知我。而你,默默地将各位大佬的电话记在一个小本子上,等你千辛万苦把bug解决发布开软件后,就按照小本子上的电话挨个打过去告知。
如果有大佬离职了,你就把他的电话号码从本子上删了,新的大佬入职就添加,就像qt中的connect和disconnect一样。
就这种模式,发个软件,我可以上告知老板、下告知扫地阿姨都是没有问题的,不管你是做什么工作的,只要给我留个电话就行(降低耦合性),当然小本子上的电话多了,一轮打下来还是吃不消的。
那有人会问,等我发布了,直接去告诉各位大佬啊,为什么一定要打电话。实现观察者模式时要注意具体目标对象和具体观察者对象之间不能直接调用,否则将使两者之间紧密耦合起来,这违反了面向对象的设计原则。
观察者模式的优缺点
优点:
- 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。
- 目标与观察者之间建立了一套触发机制。
缺点:
- 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
- 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。
实现原理
UML类图
图片来源:https://zhuanlan.zhihu.com/p/158537313
看图说明,图片右边是观察者,左边是被观察者。
所有观察者(ConcreteObserver类)都需要继承一个虚类(Observer类),然后将虚类的指针传入想要观察的对象的链表中(ObserverList),怎么传入?使用attachObserver()函数传入,使用detachObserver()删除。
然后被观察者需要发出信号时,就会调用notiifyOberver()函数,在里面遍历ObserverList链表,通过链表中的指针执行update()函数,从而达到告知各位观察者。