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. Node ExpressJs server的路径设置

    一.动态页面的路径: app.METHOD(PATH, HANDLER)Where: * app is an instance of express.* METHOD is an HTTP reque ...

  2. java.map使用

    Map以按键/数值对的形式存储数据,和数组非常相似,在数组中存在的索引,它们本身也是对象.       Map的接口       Map---实现Map       Map.Entry--Map的内部 ...

  3. Java设计模式1——策略模式(Strategy Pattern)

    最近觅得一本好书<您的设计模式>,读完两章后就能断言,一定是一头极品屌丝写的,而且是专写给开发屌丝男的智慧枕边书,小女子就委屈一下,勉强看看,人笨,谁让他写得这么通俗易懂呢!为了加深理解, ...

  4. JS-安全检测JavaScript基本数据类型和内置对象的方法

    前言:在前端开发中经常会需要用到检测变量数据类型的需求,比如:判断一个变量是否为undefined或者null来进行下一步的操作,今天在阅读“编写高质量代码-改善JavaScript程序的188个建议 ...

  5. 移动web开发实践-css3(1)盒模型display:-webkit-box;的使用

    提到移动布局不得不提到盒模型display:-webkit-box;这个属性,在移动布局中浮动已经不在重要,相反自适应成为主要的需求,所以display:-webkit-box;变得尤为重要. box ...

  6. java后台调用url无协议

    url格式不正确,可能有"www.baidu.com"    "这个不能有 // 下载pdf public void downpdf(String URL, String ...

  7. Android IOS WebRTC 音视频开发总结(八十一)-- WebRTC靠谱吗?有没有适合的SDK推荐?

    作者:blaker,最早发表在我们的微信公众和[编风网],详见[这里] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:blackerteam 或 webrtcorgcn) ...

  8. redis集群同步迁移方法(一):通过redis replication实现

           讲到redis的迁移,一般会使用rdb或者aof在主库做自动重载到目标库方法.但该方法有个问题就是无法保证源节点数据和目标节点数据保持一致,一般线上环境也不允许源库停机,所以要在迁移过程 ...

  9. Matrix QR Decomposition using OpenCV

    Matrix QR decomposition is very useful in least square fitting model. But there is no function avail ...

  10. thinkPHP-空操作

    空操作 当访问的方法不存在时,可以定义一个empty方法来避免空操作 function _empty() { echo "网页不存在,请检查地址信息"; } 这样当访问不存在的方法 ...