1.意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

2.别名

依赖(Depenents),发布-订阅(Publish-subscribe)

3.动机

一个目标可以有任意数目的依赖它的观察者。一旦目标的状态发生改变,所有的观察者都得到通知。作为这个通知的响应,每个观察者都将查询目标以使其状态于目标的同步。

4.适用性

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这二者封装在独立的对象中以使它们可以各自独立改变和复用。
  • 当一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
  • 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧耦合的。

5.结构

6.代码实例

//Subject.h

#include <memory>
#include <vector> class AbstractObserver; class AbstractSubject
{
public:
virtual void Attach(std::shared_ptr<AbstractObserver> pObserber)=;
virtual void Notify()=;
virtual void SetState(int state)=;
virtual int GetState()=;
}; class ConcreteSubject : public AbstractSubject
{
public:
ConcreteSubject();
~ConcreteSubject();
virtual void Attach(std::shared_ptr<AbstractObserver> pObserber);
virtual void Notify();
virtual void SetState(int state);
virtual int GetState();
private:
std::vector<std::shared_ptr<AbstractObserver>> m_vecObservers;
int m_state;
};
//Observer.h

#include <memory>

class AbstractSubject;

class AbstractObserver
{
public:
virtual void Update()=;
}; class ConcreteObserver1 : public AbstractObserver
{
public:
ConcreteObserver1(std::shared_ptr<AbstractSubject> pSubject);
~ConcreteObserver1();
virtual void Update();
private:
std::shared_ptr<AbstractSubject> m_Subject;
}; class ConcreteObserver2: public AbstractObserver
{
public:
ConcreteObserver2(std::shared_ptr<AbstractSubject> pSubject);
~ConcreteObserver2();
virtual void Update();
private:
std::shared_ptr<AbstractSubject> m_Subject;
}; class ConcreteObserver3 : public AbstractObserver
{
public:
ConcreteObserver3(std::shared_ptr<AbstractSubject> pSubject);
~ConcreteObserver3();
virtual void Update();
private:
std::shared_ptr<AbstractSubject> m_Subject;
};
//Subject.cpp

#include "Subject.h"
#include "Observer.h" ConcreteSubject::ConcreteSubject()
{
} ConcreteSubject::~ConcreteSubject()
{
} void ConcreteSubject::SetState(int state)
{
m_state = state;
} void ConcreteSubject::Attach(std::shared_ptr<AbstractObserver> pObserver)
{
m_vecObservers.push_back(pObserver);
} int ConcreteSubject::GetState()
{
return m_state;
} void ConcreteSubject::Notify()
{
for(auto iter = m_vecObservers.begin(); iter != m_vecObservers.end(); ++iter)
{
(*iter)->Update();
}
}
// Observer.cpp

#include "Observer.h"
#include "Subject.h"
#include <iostream> ConcreteObserver1::ConcreteObserver1(std::shared_ptr<AbstractSubject> pSubject)
: m_Subject(pSubject)
{
} ConcreteObserver1::~ConcreteObserver1()
{
} void ConcreteObserver1::Update()
{
std::cout << "ConcreteObserver1 Updated state:" << m_Subject->GetState() << std::endl;
} ConcreteObserver2::ConcreteObserver2(std::shared_ptr<AbstractSubject> pSubject)
: m_Subject(pSubject)
{
} ConcreteObserver2::~ConcreteObserver2()
{
} void ConcreteObserver2::Update()
{
std::cout << "ConcreteObserver2 Updated state:" << m_Subject->GetState() << std::endl;
} ConcreteObserver3::ConcreteObserver3(std::shared_ptr<AbstractSubject> pSubject)
: m_Subject(pSubject)
{
} ConcreteObserver3::~ConcreteObserver3()
{
} void ConcreteObserver3::Update()
{
std::cout << "ConcreteObserver3 Updated state:" << m_Subject->GetState() << std::endl;
}
//client.cpp

#include "Observer.h"
#include "Subject.h" int main()
{
std::shared_ptr<AbstractSubject> pSubject(new ConcreteSubject); std::shared_ptr<AbstractObserver> pObserver1(new ConcreteObserver1(pSubject));
std::shared_ptr<AbstractObserver> pObserver2(new ConcreteObserver2(pSubject));
std::shared_ptr<AbstractObserver> pObserver3(new ConcreteObserver3(pSubject)); pSubject->Attach(pObserver1);
pSubject->Attach(pObserver2);
pSubject->Attach(pObserver3); pSubject->SetState(); pSubject->Notify(); while();
}

7.测试结果

8.效果

  • 目标和观察者间的抽象耦合
  • 支持广播通信
  • 意外的更新 因为一个观察者并不知道其它观察者的存在,它可能对改变目标的最终代价一无所知。在目标上一个看似无害的操作可能会引起一系列对观察者以及依赖于这些观察者的那些对象的更新。此外,如果依赖准则的定义或维护不当,常常会引起错误的更新,这种错误通常难以捕捉。

Observer(观察者)-对象行为型模式的更多相关文章

  1. 设计模式 ( 十六 ) 观察者模式Observer(对象行为型)

    设计模式 ( 十六 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来 ...

  2. 设计模式18:Observer 观察者模式(行为型模式)

    Observer 观察者模式(行为型模式) 动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象) ...

  3. 设计模式(3)-对象创建型模式-Abstract Factory模式

    1.对象创建型模式 1.3           Abstract Factory模式 1.3.1 需求 在下面情况能够使用Abstract Factory模式: •  一个系统要独立于它的产品的创建. ...

  4. 设计模式(4)-对象创建型模式-Prototype模式

    1.对象创建型模式 1.4          Protoype模式 1.4.1需求 通过拷贝原形对象创建新的对象. 1.4.2结构 •P r o t o t y p e(Gr a p h i c) - ...

  5. 【设计模式】observer(观察者)-- 对象行为型模式5.7

    1.意图 对象之间一对多的依赖关系,当目标对象发生改变时,所有依赖于它的对象都要得到通知并自动更新 2.别名 依赖,发布-订阅 3.动机 1)需要确保相互协作的对象的一致性(数据要保持一致),但一致性 ...

  6. 设计模式--观察者模式Observer(对象行为型)

    一.观察者模式 观察者模式是在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新.观察者模式也被称之为:主题-观察者模式,发布-订阅模式,前者是一,后者是多. ...

  7. singleton(单件)-对象创建型模式

    1.意图 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 2.动机 对一些类来说,只有一个实例是很重要的.让类自身负责保存它唯一的实例,这个类可以保证没有其他实例可以被创建(通过截取创建新对象 ...

  8. 迭代器模式/iterator模式/对象行为型模式

    意图 又名:游标(Cursor): 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示. 动机 一个聚合对象,提供访问元素的方法,而有不暴露它的内部结构.如list,将对列表的访问 ...

  9. Mediator(中介者)-对象行为型模式

    1.意图 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 2.动机 通过将集体行为封装在一个单独的中介者对象中,中介者 ...

随机推荐

  1. 对"QQGame-大家来找茬"的辅助工具的改进

    [前言]最近在博客园首页上看到有“大家来找茬”这个游戏(此游戏为找出两个相近图片的不同点)外挂的相关帖子,所以这里我也翻看了我之前(2009年5月)的写的一个简单的辅助程序(采用 VC6 开发的).我 ...

  2. mount什么意思

    root@Home-Cloud:/mnt# dfFilesystem           1K-blocks      Used Available Use% Mounted on/dev/root  ...

  3. RDD常用方法之subtract&intersection&cartesian

    subtract Return an RDD with the elements from `this` that are not in `other` .     def subtract(othe ...

  4. Ibatis.net总是报:【ExecuteStoreCommand SqlParameterCollection 中已包含 SqlParameter】(转)

    今天很奇怪调用EF的ExecuteStoreCommand 出现了个这样的错误,怎么也调试不过,痛定思痛 原来 command被连着调用了而没有销毁掉   public static DataTabl ...

  5. 单片机中用c编程时头文件reg51.h及reg52.h解析

    单片机中用c编程时头文件reg51.h及reg52.h解析 我们在用c语言编程是往往第一行就是reg51.h或者其他的自定义头文件,我们怎么样来理解呢? 1)“文件包含”处理. 程序的第一行是一个“文 ...

  6. 启动kafka出现找不到或无法加载主类

    首先确认下环境变量配置是否成功. 如果配置成功<javac,javah>都没有问题,那就有可能是你安装了两个版本的jdk导致的,都卸载了,然后换一个目录按照一个jdk 在配置环境变量试下!

  7. sql中limit使用方法

    此处以mysql为例,但是我相信物以变通在oracle上也一定适用 下面是几种limit的方法:原则看看下面几个例子应该就懂了 在数据库中很多地方都会用到,比如当你数据库查询记录有几万.几十万时使用l ...

  8. 嵌入式: jffs2,yaffs2,logfs,ubifs文件系统性能分析

    在嵌入式领域,FLASH是一种常用的存储介质,由于其特殊的硬件结构,所以普通的文件系统如ext2,ext3等都不适合在其上使用,于是就出现了专门针对FLASH的文件系统,比较常用的有jffs2,yaf ...

  9. php学习笔记

    header("Content-Type:text/html;charset=utf-8");//设置中文请求中文 $host = "localhost";// ...

  10. Window 对象详解 转自 http://blog.csdn.net/jcx5083761/article/details/41243697

    详解HTML中的window对象和document对象 标签: HTMLwindowdocument 2014-11-18 11:03 5884人阅读 评论(0) 收藏 举报 分类: HTML& ...