观察者模式

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

作用

将一个系统设计成一系列相互协作的类有一个常见的副作用:需要维护相关对象之间的一致性。

观察者模式定义一种交互:

  1. 一个对象当自身状态发生改变时,会发出通知,但是并不知道谁是他的接收者,但每个接收者都会接收到通知,这些接受者称为观察者。
  2. 作为对通知的响应,每个观察者都将查询目标状态,然后改变自身的状态以和目标状态进行同步

使用场景

  1. 使对象封装为独立的改变和使用;
  2. 一个对象改变同时需要改变其它对象,而不知道具体有多少对象需要改变;
  3. 不希望对象是紧耦合的。

UML

参与者

  • CSubject: 目标,知道它的观察者,提供注册和删除观察者对象的接口
  • CObserver:观察者,为那些在目标发生改变时需获得通知的对象定义一个更新接口
  • CConcreteSubject:通知所有观察者
  • CConcreteObserver:接受目标的通知

优缺点

  • 目标和观察者之间松耦合
  • 支持广播通信:CSubject发送的通知不需要指定它的接受者。通知被自动广播给所有已向该目标对象登记的有关对象。
  • 意外的更新:看似无害的操作可能会引起观察者错误的更新。

代码

#include <string>
#include <list>

class CObserver;

class CSubject
{
public:
    virtual ~CSubject() {}
    virtual void attach(CObserver* ob) = 0;
    virtual void detach(CObserver* ob) = 0;
    virtual void notify(const std::string & msg) = 0;
};

class CConcreteSubject : public CSubject
{
public:
    CConcreteSubject() = default;
    virtual ~CConcreteSubject() = default;
    void attach(CObserver* ob) override;
    void detach(CObserver* ob) override;
    void notify(const std::string & msg) override;

private:
    std::list<CObserver*> listObserver_;
};

class CObserver
{
public:
    virtual ~CObserver() {}
    virtual void update(const std::string & msg) = 0;
};

class CConcreteObserver : public CObserver
{
public:
    CConcreteObserver() = default;
    CConcreteObserver(const std::string & strName);
    virtual ~CConcreteObserver() = default;
    void update(const std::string & msg) override;

private:
    std::string strName_;
};
#include <iostream>

#include "observer.h"


void CConcreteSubject::attach(CObserver *ob)
{
    listObserver_.push_back(ob);
}

void CConcreteSubject::detach(CObserver *ob)
{
    listObserver_.remove(ob);
}

void CConcreteSubject::notify(const std::string & msg)
{
    for (CObserver * ob : listObserver_)
    {
        ob->update(msg);
    }
}


CConcreteObserver::CConcreteObserver(const std::string & strName) : strName_(strName) {}

void CConcreteObserver::update(const std::string &msg)
{
    std::cout << this->strName_ << " get message: " << msg << std::endl;
}
#include "observer.h"

int main()
{
    CConcreteObserver a("jack ma");
    CConcreteObserver b("pony ma");
    CConcreteObserver c("robin li");
    CConcreteObserver d("jobs");
    CConcreteObserver e("gates");

    CConcreteSubject obj;
    obj.attach(dynamic_cast<CObserver*>(&a));
    obj.attach(dynamic_cast<CObserver*>(&b));
    obj.attach(dynamic_cast<CObserver*>(&c));
    obj.attach(dynamic_cast<CObserver*>(&d));
    obj.attach(dynamic_cast<CObserver*>(&e));

    obj.notify("hello");

    return 0;
}

 

posted @ 2019-01-10 11:14  二狗啸地  阅读(168)  评论(0编辑  收藏  举报