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. php+mysql预查询prepare 与普通查询的性能对比

    prepare可以解决大访问量的网站给数据库服务器所带来的负载和开销,本文章通过实例向大家介绍预查询prepare与普通查询的性能对比,需要的朋友可以参考一下. 实例代码如下: <?php cl ...

  2. public static void Invoke (Action action)

    using System; using System.Security.Principal; using System.Security.Permissions; namespace Demo { c ...

  3. 思考力——提升企业竞争力的核心因素

    如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 · 思考力就是竞争力:在这个科技飞跃进步的时代,很多事物是我们未曾经历也难以预料的. ...

  4. MySql绿色版下载,安装,配置详解

    下载完成之后解压,楼主用的版本是:mysql-5.7.15-winx64 解压完在根目录下建立一个data文件夹和my-default.ini my-default.ini里面的内容如下:(红色内容根 ...

  5. 如何创建vss2005的数据库

    配置如下 VSS手工创建数据库的步骤(设数据库根目录为D:\VSS): 1.在根目录中创建名为srcsafe.ini(全局配置文件)的文件,文件内容如下: Data_Path = data Temp_ ...

  6. iOS开发 GET、POST请求方法(NSURLSession篇)

    NSURLConnection,在iOS9被宣布弃用,本文不使用NSURLConnection进行网络编程,有兴趣的童鞋可以参考: [iOS开发 GET.POST请求方法(NSURLConnectio ...

  7. python脚本基础总结

    1. 注释 ①单行注释:#单行注释 ②多行注释: ''' 三个单引号,多行注释符 ''' ③中文注释:#coding=utf-8 或者 #coding=gbk 2.输入输出 ① 输入:  3.0后的p ...

  8. SSH Tunneling

    把本地端口 local_port 转发到服务器 server2 的 remote_port 端口上, server1 和 server2可以是同一ip或者不同ip. ssh user@server1 ...

  9. 表中排序ID断开重排

    客户需要排序ID和页面的问题序号一致,以前删除过一些问题导致order_id 中间有些断开的. 业务表 T_QUESTION order_id question_id  custom_id --1.创 ...

  10. Value must be an existing directory配置tomcat问题

    今天tomcat配置遇到了这么个问题,表示tomcat下少什么文件夹,一般是你的安装目录tomcat文件夹下面少了一个temp文件夹,在tomcat的安装文件夹下建一个temp文件夹再加一次tomca ...