观察者模式
观察者模式定义类对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
观察者模式是一种一对多的模式,主题中的数据发生变化,会通知所有订阅了主题的观察者,使得他们更新自己。
notifyObserver在主题数据发生变化时,通知所有在主题中注册的观察者,让他们调用Update函数。因此具体的主题类中应该有一个用于存放注册观察者的数据结构。
推类型观察者模式
对于推类型的观察者模式,传递的参数类型最好是用户自己新定义的类型,因为这样在后面数据变多的时候,只需要在定义的新类型中发生改变,不用从Observer的接口update函数一直到所有子类都进行修改。
拉类型观察者模式
对于拉类型的观察者模式,最好传输主题自身的一个指针,并实现数据的get接口,让观察者自身获取需要的信息(减少了推协议中传输大量数据的问题,但是却需要实现大量的get方法)。
松耦合的威力
主题和观察者之间是松耦合的,因为他们彼此之间可以交互,但是不知道对方的实现细节,只知道对方实现了某些接口。
当出现新的观察者的时候,主题不需要作出修改,我们新的类型的观察者只需要实现观察者所必须要实现的接口就可以注册到主题中,主题不在乎观察者的实现,在数据发生改变时会通知所有的观察者。
设计原则
为了交互对象之间的松耦合设计而努力。
1
改变主题或观察者其中一方,并不会影响另一方。因为两者是松耦合的,所以只要他们之间的接口仍然被遵守,我们就可以自由地改变他们。送耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的相互依赖降到了最低。
一些细节
给主题内部实现一个setChange函数。往往很多时候发生一些微小的改动的时候,我们是不想通知观察者进行改变的。例如天气变化,也许在变化不超过0.1摄氏度的时候,我们不想让天气显示板发生那些微小的变化(在我们对这些微小变化不关心的时候,而且这些微小变化时刻发生,大量的数据传输存在很大压力),我们可以根据我们希望看到的变化幅度,执行setChange函数,设置changed的值为true,只有在changed的值为true(达到我们希望看到的变化幅度的时候),我们通知所有观察者。通知过后再将changed值设为false。
观察者模式中遵守的设计原则
分离变化与不变化
1
在观察者模式中,主题的状态和观察者的数目是会改变的。观察者模式可以改变依赖于主题的观察者,却不需要改变主题。
针对接口编程,不针对实现编程
1
主题和观察者都使用接口,观察者利用主题接口进行注册,主题利用观察者接口通知观察者。
多用组合,少用继承
1
使用组合将注册 的观察者放进主题中。
参考书籍:
《Head First设计模式》
1
FIN 5.23/1.07