观察者模式
2021-08-07
3 min read
观察者模式
观察者模式是开发中常用的设计模式之一,C++Qt库中的信号槽机制就是观察者模式的典型代表,关于信号槽机制的原理与简化实现,读者可自行查阅相关资料;
本文仅对观察者模式做一个简要介绍:
目的
实现类似 “发布-订阅” 这样的需求,且信息发布者与订阅者之间应当是松耦合,以使得发布者与订阅者独立变化,信息发布者只要广播信息而无需了解具体的信息订阅者,同时信息订阅者可以自行决定如何响应;
概念
定义对象间一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖于它的对象都得到通知并自动更新;
示例
观察者模式中信息发布者与订阅者需要松耦合设计,实现松耦合的重要方式就是多态技术,即利用类继承与虚函数重写来对不同的类约定相同的函数接口,C++示例代码如下:
#ifndef OBSERVER_H
#define OBSERVER_H
#include <list>
#include <algorithm>
#include <iostream>
class AbstractObserver {
public:
AbstractObserver();
virtual ~AbstractObserver();
virtual void update() {
std::cout << "AbstractObserver update." << std::endl;
// ...
}
// ...
};
class Observer1 : public AbstractObserver {
public:
virtual void update() override {
std::cout << "Observer1 update." << std::endl;
// ...
}
};
class Observer2 : public AbstractObserver {
public:
virtual void update() override {
std::cout << "Observer2 update." << std::endl;
}
};
class Observer3 : public AbstractObserver {
public:
virtual void update() override {
std::cout << "Observer3 update." << std::endl;
}
};
class Publisher {
public:
void addSubscriber(AbstractObserver * observer) {
auto itor = std::find(m_observers.cbegin(), m_observers.cend(), observer);
if (itor != m_observers.cend()) {
std::cout << "Add failed : duplicated add." << std::endl;
return;
}
m_observers.push_back(observer);
}
void removeSubscriber(AbstractObserver * observer) {
m_observers.remove(observer);
}
void publish() {
for (AbstractObserver* ele : m_observers) {
ele->update();
}
}
// ...
private:
std::list<AbstractObserver*> m_observers;
};
#endif // OBSERVER_H
主函数:
#include <memory>
#include "observer.h"
using std::unique_ptr;
int main()
{
unique_ptr<AbstractObserver> observer1 = std::make_unique<Observer1>();
unique_ptr<AbstractObserver> observer2 = std::make_unique<Observer2>();
unique_ptr<AbstractObserver> observer3 = std::make_unique<Observer3>();
Publisher publisher;
publisher.addSubscriber(observer1.get());
publisher.addSubscriber(observer2.get());
publisher.addSubscriber(observer3.get());
publisher.publish();
publisher.removeSubscriber(observer2.get());
publisher.publish();
// ...
return 0;
}
参考
本文参考 同 本博客前述<面向对象设计>一文中所参考项;
版权声明:
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!