观察者模式实现老板状态变化通知 C++

81 篇文章 0 订阅
29 篇文章 1 订阅

说下对观察者模式的理解:
观察者模式定义了一种一对多的依赖关系, 让多个观察者对象可以同时监听某一主题对象, 当这个主题对象的状态发生改变的时候, 就会通知所有的观察者对象, 使他们可以自动更新自己。
subject 类, 一般称为主题类或者通知者类, 一般可以使用一个抽象类或者一个接口来实现, 他提供接口可以增加或者删除观察者对象。
observer 类, 一般使用抽象类或者接口实现。
当将一个系统分割成一系列相互协作的类的时候, 通常有个很不好的副作用,就是需要维护相关对象之间的一致性关系,但是, 我们又不希望因为需要维护一致性, 而造成各个类之间紧密耦合的现象, 这样会给维护,扩展和重用带来不便。
观察者模式的使用情形:
当一个对象的改变需要同时改变其他对象的时候。并且他并不知道具体会有多少对象有待改变的时候, 就需要考虑使用观察者模式了。
当一个抽象模型有两个方面, 其中一方面依赖另一方面时, 使用观察者模式可以将这两者封装在独立的对象中, 使他们各自独立的改变和复用。
观察者模式实际上做的是解除耦合, 让耦合的双方都依赖于抽象, 而不是具体实现, 从而使得各自的变化都不会影响另一边的变化。
当然, 观察者模式有一个缺点:
抽象通知者还是依赖于抽象观察者, 也就是说万一没有了抽象观察者的这样的接口, 就无法实现通知功能了。

virtual void Notify(){ for_each(objList.begin(), objList.end(), [](CIObserver * obj){obj->update(); }); }

当我们需要,由客户端指定通知对象的时候,这个模式就遇到了困难, .net 中为我们提供了事件委托机制, 可以解决这个问题, 这里不再多说。

UML图:
这里写图片描述

运行效果图:
这里写图片描述

代码如下:
observer.h

#ifndef _OBSERVER_H_
#define _OBSERVER_H_

#include <string>
using std::string;

class CISubject;

/************************************************************************/
/* 观察者基类                                                           */
/************************************************************************/
class CIObserver{
public:
    CIObserver(CISubject * sub, string name) : subject(sub), name(name){}
    virtual void update() = 0;

protected:
    string name;
    CISubject * subject;
};

#endif

mainobserver.h

#ifndef _MAINOBSERVER_H_
#define _MAINOBSERVER_H_

#include "observer.h"
#include "subject.h"
#include <string>
#include <iostream>

using std::string;
using std::cout;
using std::endl;

/************************************************************************/
/* 股票观察者                                                           */
/************************************************************************/
class CStockObserver : public CIObserver{
public:
    CStockObserver(CISubject * subject, string name) : CIObserver(subject, name){}
    void update(){ cout << subject->SubjectState() << name << "关闭股票行情, 继续工作" << endl; }
};

/************************************************************************/
/* NBA 观察者                                                           */
/************************************************************************/
class CNBAObserver : public CIObserver{
public:
    CNBAObserver(CISubject * subject, string name) : CIObserver(subject, name){}
    void update(){ cout << subject->SubjectState() << name << "关闭NBA直播, 继续工作" << endl; }
};

#endif // _MAINOBSERVER_H_

subject.h

#ifndef _SUBJECT_H_
#define _SUBJECT_H_

#include "observer.h"

#include <list>
#include <algorithm>
#include <string>

using std::list;
using std::string;

/************************************************************************/
/* 通知者接口                                                           */
/************************************************************************/
class CISubject{
public:
    virtual void Attach(CIObserver * obj){ objList.push_front(obj); }
    virtual void Detach(CIObserver * obj){ objList.pop_front(); }
    virtual void Notify(){ for_each(objList.begin(), objList.end(), [](CIObserver * obj){obj->update(); }); }

    string SubjectState() const { return subjectState; }
    void SubjectState(string val) { subjectState = val; }

private:
    list<CIObserver *> objList;
    string subjectState;
};

#endif // _SUBJECT_H_

mainsubject.h

#ifndef _MAINSUBJECT_H_
#define _MAINSUBJECT_H_

#include "subject.h"

/************************************************************************/
/* 通知者 boss                                                          */
/************************************************************************/
class CBoss : public CISubject{};

/************************************************************************/
/* 通知者 secretary                                                     */
/************************************************************************/
class CSecretary : public CISubject{};

#endif // _MAINSUBJECT_H_

main.cpp

#include "MainObserver.h"
#include "MainSubject.h"

#include <iostream>
#include <memory>

using namespace std;

int main(){
    shared_ptr<CBoss> boss(new CBoss);
    shared_ptr<CStockObserver> stock(new CStockObserver(boss.get(), "lisi"));
    shared_ptr<CNBAObserver> nba(new CNBAObserver(boss.get(), "zhangsan"));

    boss->Attach(stock.get());
    boss->Attach(nba.get());

    //boss->Detach(nba.get());

    boss->SubjectState("我是老板, 我回来了, 大家有没有认真工作啊?");
    boss->Notify();

    system("pause");
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值