设计模式:观察者模式(C++实现)

1. 应用背景

观察者模式模式又称为发布-订阅模式。订阅消息的一方称为观察者,而发布消息的一般称为主题类。观察者在一开始的时候会向主题类注册自己感兴趣的事件,当主题类发布了一个特定事件的时候,观察者就会收到主题类的通知,从而完成状态变化。

在实际应用上,比如主题类是一组数据,由这组数据可以绘制出饼图、折线图、柱状图等统计图形。那么观察者就可以分别是以上三种图形。当数据发生变化的时候,统计图形也需要发生相应的变化。

2. 实现过程

在下面的例子中,我们首先先设计了一个观察者基类:ObserverBase。这个类是作为抽象类规范接口用的,所有的观察者有统一的接口,方便主题类调用。

其次,不同的观察者从ObserverBase进行继承,然后重写接口,完成某个消息到达时自己业务的封装。

而对于主题类而言,最主要的是提供两个接口:一个用于给观察者注册观察特定信号:addObserver,一个用于新的信号发生时通知观察者:dispatch。对于注册,我们使用了哈希表+链表的数据结构来维护观察者的信息。对同一个事件感兴趣的观察者被链接在同一个list上,发生事件时依次进行通知。

以下是具体实现:

#include <iostream>
#include <unordered_map>
#include <list>
using namespace std;

class ObserverBase {
public:
	virtual void handleMessage() = 0;
};

class Observer1 : public ObserverBase {
public:
	void handleMessage() {
		cout << "Handle Message 1!" << endl;	
	}
};

class Observer2 : public ObserverBase {
public:
	void handleMessage() {
		cout << "Handle Message 2!" << endl;
	}
};

class Subject {
public:
	void addObserver(ObserverBase* obj, int messageId) {
		subList_[messageId].push_back(obj);
	}
	// 主题发生变化,通知观察者
	void dispatch(int newMsg) {
		auto it = subList_.find(newMsg);
		if (it != subList_.end()) {
			for (auto curObj : subList_[newMsg]) {
				curObj->handleMessage();
			}
		}
	}

private:
	unordered_map<int, list<ObserverBase*>> subList_;
};

int main() {
	// 主题类
	Subject* sub = new Subject();
	// 观察者
	Observer1* obj1 = new Observer1();
	Observer2* obj2 = new Observer2();

	// 观察者1对信号1感兴趣
	sub->addObserver(obj1, 1);
	// 观察者2对信号2感兴趣
	sub->addObserver(obj2, 2);

	// 新信号来了
	sub->dispatch(1);
	sub->dispatch(2);
	sub->dispatch(1);

	return 0;
}

运行结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值