● 意图
1> 在N个对象之间,建立一对多的联系:一个对象(主体)状态改变,其它对象(客体)都得到通知,并且做出相应的更新。
2> 核心、通用的模块,封装到主体类;因个体而异的可变的功能,封装到客体类。
3> 实现MVC体系中的View。
● 问题
一个软件设计在规模逐渐庞大时,其“图形化系统”/“监视系统”如果和系统耦合较紧,则做不到相应的、很好的更新。此时,可用observer模式进行重构。
● 实现步骤
1> 找到应用程序中相似的、可选的、并行的、外围的功能/模块。
2> 给它们定义一个通用接口(最好是个抽象类),这样它们就具备了互换性,多态了,可在运行时自适应自己的行为。此之为:observer。
3> 然后给各个相似、可选、并行、外围的模块,都定义一个派生类。
4> 找到应用程序中核心、通用功能/模块,封装到一个主体类。主体只和上面定义的抽象observer相耦合。
5> 客户在使用时,把那些相似、可选、外围的对象,全都注册给这个主体对象。
6> 程序运行时,不用单独地和那些外围模块交互。它只需要调用那个“核心”,发布一个广播即可。
7> 所有的外围对象接收到“更新”通知,做出相应的改变。还可以做主体的回调。
● 讨论
所谓“主体”,就是程序的数据模型、应用逻辑。把所有外围的功能,交给互相并不耦合的客体。客体在主体上注册。主体用广播的形式通知所有客体。客体用查询的形式监视主体的变量。
这样,外围功能的类型、数量就全都可以在运行时决定。
这是一种“被动查询式”的交互模型,也可以用“主动推送式”模型。推送式交互限制了重用;查询式交互效率低。
设计者要考虑:广播的数目、类型不能太多;是否允许一个客体同时监视多个主体;主体销毁前要通知客体。
●结构图
● 重构前的例子(主体客体耦合在一起):
● 重构后