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

文章目录

  • 1. 应用背景
  • 2. 实现过程

1. 应用背景

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

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

2. 实现过程

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

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

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

以下是具体实现:

#include 
#include 
#include 
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;
}

运行结果:

设计模式:观察者模式(C++实现)_第1张图片

你可能感兴趣的:(设计模式,设计模式,观察者模式,c++)