观察者模式——C++实现
1. 观察者模式简介
观察者模式又叫做发布订阅模式,它是一种行为型模式。
假如我们要开发一款图表绘制程序,其中有一个环节就是根据最新的数据绘制饼图和折线图,并且当数据更新的时候,饼图和折线图能够及时地进行更新。
一般情况下我们会怎么做呢?我们的直接想法可能就是,每隔一段时间去检查一下,数据有没有更新。而且为了能够及时更新的图表,检查的时间间隔不能太长。那么检查的间隔时间太短又会浪费CPU的时间做无用功。
这种每隔一会就检查一下的办法看起来就笨笨的,而且吃力不讨好,可能检查了好多遍数据都没有变。要是数据发生变化的时候能够自动通知我们就好了,等它来通知我们的时候,我们再去根据最新的数据进行图表的绘制。这样就能大大提高效率,减少无用的操作了。
很好!你已经发现了观察者模式!(或者说发布订阅模式)
这个模式涉及到了两种对象:主题对象(Subject)和观察者对象(Observer)。主题对象负责维护一个主题,这个主题可以是任何我们关心的数据。主题对象还会记录当前有哪些观察者对象订阅了该主题。当主题发生变化的时候,主题对象会自动通知这些观察者对象。
以上就是观察者模式的核心概念,下面通过一个简单的小栗子来看看到底是怎么回事。
2. 观察者模式的小栗子
依然以上面提到的图表绘制程序作为示例,代码如下:
#include <iostream>
#include <vector>
using namespace std;
class Observer;
class Subject {
public:
virtual void attach(Observer* observer) = 0;
virtual void detach(Observer* observer) = 0;
virtual void notify() = 0;
};
class Observer {
public:
virtual void update(const vector<int>& data) = 0;
};
class ConcreteSubject : public Subject {
private:
vector<Observer*> observers;
vector<int> data;
public:
void attach(Observer* observer) {
observers.push_back(observer);
}
void detach(Observer* observer) {
observers.erase(remove(observers.begin(), observers.end(), observer), observers.end());
}
void notify() {
for (auto observer : observers) {
observer->update(data);
}
}
void setData(const vector<int>& newData) {
data = newData;
notify();
}
};
class PieGraphObserver : public Observer {
public:
void update(const vector<int>& data) {
cout << "使用数据绘制饼图:";
for (auto num : data) {
cout << num << " ";
}
cout << endl;
}
};
class LineGraphObserver : public Observer {
public:
void update(const vector<int>& data) {
cout << "使用数据绘制折线图:";
for (auto num : data) {
cout << num << " ";
}
cout << endl;
}
};
int main() {
ConcreteSubject* subject = new ConcreteSubject();
Observer* pieObserver = new PieGraphObserver();
Observer* lineObserver = new LineGraphObserver();
subject->attach(pieObserver);
subject->attach(lineObserver);
cout << "---------------" << endl;
cout << "数据更新为: 1 2 3" << endl;
vector<int> data1 = { 1, 2, 3 };
subject->setData(data1);
cout << endl << endl;
cout << "---------------" << endl;
cout << "数据更新为: 4 5 6" << endl;
vector<int> data2 = { 4, 5, 6 };
subject->setData(data2);
cout << "lineObserver 注销观察" << endl;
subject->detach(lineObserver);
cout << endl << endl;
cout << "---------------" << endl;
cout << "数据更新为: 4 5 6" << endl;
vector<int> data3 = { 7, 8, 9 };
subject->setData(data3);
delete subject;
delete pieObserver;
delete lineObserver;
return 0;
}

其中,Observer类就是我们的抽象观察者类,Subject就是我们的抽象主题类。提供了attach用来添加观察者,detach用来注销观察者,notify用来通知观察者。
PieGraphOvserver是具体的饼图观察者类,用来绘制饼图。
LineGraphObserver是具体的折线图观察者类,用来绘制折线图。
ConcreteSubject是具体的主题类,通过vector维护了对主题进行观察的观察者,以及当前的数据。可以通过setData来更新数据。
当我们使用setData来更新数据时,就会自动调用notify来通知所有的观察者,并把最新的数据交给他们,他们各自也会通过他们的手段来更新图表。
以上就是观察者模式的讲解,感谢大家看到这里,写的不严谨,敬请批评指正。
更多推荐
所有评论(0)