设计模式--观察者模式

观察者模式是一种对象行为模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。模式适用于当一个对象的改变需要同时改变其他对象,且不知道具体有多少对象需要改变的情况。其优点包括解耦目标与观察者,支持广播通信,但可能导致意外更新和悬挂调用等问题。实现时要注意目标状态的一致性,避免特定更新协议,以及封装复杂的更新语义。
摘要由CSDN通过智能技术生成

观察者模式又称发布–订阅模式,是属于对象行为性的一种设计模式。
首先是观察者模式的定义:
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个对象,当这个主题对象发生改变的时候,会通知所有的观察者对象,使他们能自动更新自己。
此模式的结构图:
这里写图片描述
适用性:
1 当一个抽象模型有两个方面,其中一个方面依赖于另外一个方面,将这两个对象封装在独立的对象中以使他们独立的发生改变和复用
2 当一个对象的改变需要通知多个对象发生变化,而又不知道有多少个对象的时候
3 当一个对象必须通知其他对象,而又不能假定其他对象是谁的时候。
协作
1 当concreteSubject发生任何可能导致其观察者对象与其本身的状态不一致的改变时,它将通知它的各个观察者
2 在得到一个具体的改变通知后,ConcreteObserver对象可向目标对象查询信息,ConcreteObserver使用这些信息以使他的状态与目标对象的状态一致
优点
1 目标和观察者的解耦,在分层的结构当中,由于底层的对象可能要通知高层的对象发生改变,如果目标和观察者混在一块,破坏了系统的层次性。
2 支持广播通信,发送通知者不需要知道是谁接收了通知,而接收通知的对象可以选择处理或者不处理
缺点
1 意外的更新,由于通知者不知道观察者,在通知者看上去合理的操作,但可能会引起观察者的改变,从而导致很难查找的BUG
实现
1 创建目标与观察者对象的映射,最简单的方式是直接在目标对象中使用引用,但如果对象太多,开销会很大。如果用时间换空间的话,可以采用hash表,但增加了另外访问观察者的开销
2 观察多个目标,观察者知道是哪一个对象发来的通知,有时是很有必要的,因此可以扩展update把发送者的引用传过来
3 谁触发更新,有两个选择
1 目标对象的状态设定改变后自动调用Notify,
优点:客户不需要记住要在目标对象调用Notify
缺点:多个连续的操作会导致多个更新,效率较慢
2 让客户在合适的时候调用Notify.
优点:客户可以在一系列的改变后在调用Notity,避免不必要的中间状态的更新,效率较高
缺点:由客户控制更新的时机,有可能客户会忘记调用
4 对以删除的对象的悬挂调用,当删除一个对象时,该对象可能被其他对象引用,应该通知他的所有观察者,使所有的引用复位
5 在发出通知时确保目标的状态自身是一致的,因为观察者在更新其状态时需要查询目标的当前状态
6 避免特定与观察者的更新协议–推/拉模型
推模型:目标状态改变后就向观察者发出通知,不管观察者需要与否
缺点:观察者可能难以复用
拉模型:观察者主动向目标询问
缺点:效率很差
7 显示指定感兴趣的操作,观察者注册一个感兴趣的操作,当这个操作完成后通知观察者,可以提高效率
8 封装复杂的更新语义,当观察者的依赖关系比较复杂的时候,需要一个更改管理器,当所有的依赖更改都完成后才通知,不是每个目标都通知
具体的责任:
1 负责管理观察者与目标之间的引用关系
2 定义一个特定的更新
3 更加目标的请求,更新所有依赖与这个目标的更新
9 结合目标类和观察者类,将观察者和目标结合在一个类中,可以不使用多重继承
例子:

// ObserverModel.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "Boss.h"
#include "StockObserver.h"
#include "NbaObserver.h"


int _tmain(int argc, _TCHAR* argv[])
{
    Boss* boss = new Boss;

    StockObserver* sObserver = new StockObserver("
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值