Observer(观察者)-对象行为型模式

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)=0;
    virtual void Notify()=0;
    virtual void SetState(int state)=0;
    virtual int GetState()=0;
};

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()=0;
};

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(5);

    pSubject->Notify();

    while(1);
}

7.测试结果

8.效果

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

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

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

Observer 观察者模式(行为型模式) 动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象)都将得到通知.如果这样的以来对象关系过于紧密,将使软件不能很好地抵御变化. 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系.从而实现软件体系结构的松耦合. 意图(Intent) 定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更

生成器模式(Builder)-- 对象创建型模式

1. 动机 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.一个RTF(Rich Text Format)文档交换格式的阅读器应能将RTF转换为多种正文格式.该阅读器可以将RTF文档转换成普通ASCII文本或转换成一个能以交互方式编辑的正文窗口组件.但问题在于可能转换的数目是无限的.因此要能够很容易实现新的转换的增加,同时却不改变RTF阅读器.其实也就是,前面的数据接卸(源头处理)归解析,后续的显示处理,由显示处理的部分来完成.在数据解析和显示处理之间架设一个标准的桥梁

设计模式(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) - 声明一个克隆自身的接口. ?C o n c r e t e P r o t o t y p e(S t a ff.W h o l e N o t e.H a l fN o t e) - 实现一个克隆自身的操作. ?  C l i e n t(G r a p h i c To o l) - 让一个原

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

1.对象创建型模式 1.3           Abstract Factory模式 1.3.1 需求 在下面情况能够使用Abstract Factory模式: ?  一个系统要独立于它的产品的创建.组合和表示时(这个需求和FactoryMethod类似). ?  一个系统要由多个产品系列中的一个来配置时(这个需求也和Factory Method类似). ?  当你要强调一系列相关的产品对象的设计以便进行联合使用时(这个需求表明一个工厂要创建多个相关的产品对象,是比FactoryMethod多的

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

1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来说,当某个对象的状态发生改变时,你仍然需要对象之间能互相通信.但是出于各种原因,你也许并不愿意因为代码环境的改变而对代码做大的修改.也许,你只想根据你的具体应用环境而改进通信代码.或者,你只想简单的重新构造通信代码来避免类和类之间的相互依赖与相互从属. 2.问题 当一个对象的状态发生改变时,你如何通知其他对象?是否需要一个动态方案――一个就像允许脚本的执行一样,允

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

一.观察者模式 观察者模式是在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新.观察者模式也被称之为:主题-观察者模式,发布-订阅模式,前者是一,后者是多. 二.UML类图 三.示例 //观察者 class Observer { public: Observer() {} virtual ~Observer() {} virtual void Update() {} }; //博客 class Blog { public: Blog() {} virt

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

1.意图 保证一个类仅有一个实例,并提供一个访问它的全局访问点. 2.动机 对一些类来说,只有一个实例是很重要的.让类自身负责保存它唯一的实例,这个类可以保证没有其他实例可以被创建(通过截取创建新对象的请求),并且它可以提供一个访问该实例的方法. 3.适用性 当类只能有一个实例而且客户可以从一个周所周知的访问点访问它时. 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时. 4.结构 5.代码实例 #include <iostream> #include

ProtoType(原型)-对象创建型模式

1.意图 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2.动机 通过拷贝或者"克隆"一个类的实例来创建新的实例. 3.适用性 当一个系统应该独立于它的产品创建.构成和表示时,要使用Prototype模式:以及 当要实例化的类是在运行时刻指定时,例如,通过动态装载:或者 为了避免创建一个与产品类层次平行的工厂类层次时或者 当一个类的实例只能有几个不同状态组合中的一种时.建立相应数目的原型并克隆它们,可能比每次用合适的状态手工实例化该类更方便一些. 4.结构 5.代码

TryBestToCode Iterator(迭代器)-对象行为型模式

1.意图 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示. 2.别名 Cursor-游标. 3.动机 一个聚合对象,应该提供一种方法来让别人可以访问它的元素,而又不需暴露它的内部结构. 4.适用性 访问一个聚合对象的内容而无需暴露它的内部表示. 支持聚合对象的多种遍历. 为遍历不同的聚合结构提供一个统一的接口,即,支持多态迭代. 5.结构 6.效果 迭代器模式有三个重要的作用: 支持以不同的方式遍历一个聚合,复杂的聚合可用多种方式进行遍历. 迭代器简化了聚合的接口,有了