赞
踩
本文介绍观察者模式以及使用函数式编程替代简单的策略模式。
观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。
当对象间存在一对多关系时,则使用观察者模式(Observer
Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。
简单来说,观察者模式需要多个对象观察同一个对象,被观察的对象称为Subject(主题),Subject需要完成观察者的注册(attach),注销(detach)和通知(notify)三个操作。
首先实现一个公共的Observer父类,这个父类只有一个纯虚函数,用来更新自身状态:
struct Observer
{
public:
virtual void update() = 0;
};
两个具体的类,实现 update 函数:
struct ConcreteObserver : Observer { public: void update() override { std::cout << "State updated!" << std::endl; } }; struct ConcreteObserver2 : Observer { public: void update() override { std::cout << "State updated! 2" << std::endl; } };
接下来实现被观察者公共类,包含添加、删除、通知所有观察者三个接口:
struct Subject
{
public:
virtual void attach(Observer *observer) = 0;
virtual void detach(Observer *observer) = 0;
virtual void notify() = 0;
};
具体的被观察者类,实现这三个接口:
struct ConcreteSubject : Subject { public: void attach(Observer *observer) override { observers.push_back(observer); } void detach(Observer *observer) override { for (auto it = observers.begin(); it != observers.end(); it++) { if (*it == observer) { observers.erase(it); break; } } } void notify() override { for (auto &observer : observers) { observer->update(); } } private: std::vector<Observer *> observers; };
测试代码如下:
int main()
{
ConcreteSubject subject;
ConcreteObserver observer1;
ConcreteObserver2 observer2;
subject.attach(&observer1);
subject.attach(&observer2);
subject.notify();
subject.detach(&observer1);
subject.notify();
}
首先需要介绍下C语言的函数指针。所谓函数指针即定义一个指向函数的指针变量,格式如下:
typedef void (*Callback)();
这样就定义了一个变量名为Callback
的指针变量,指向一个参数为void
,返回值也为void
的函数。我们用这种指针变量,就能将整个观察者类改成函数。
两个观察者函数:
void callback1()
{
std::cout << "State updated!" << std::endl;
}
void callback2()
{
std::cout << "State updated! 2" << std::endl;
}
被观察的类。原先调用观察者类的地方全部改为函数调用:
struct ConcreteSubject { public: void attach(Callback callback) { observers.push_back(callback); } void detach(Callback callback) { for (auto it = observers.begin(); it != observers.end(); it++) { if (*it == callback) { observers.erase(it); break; } } } void notify() { for (auto &observer : observers) { observer(); } } private: std::vector<Callback> observers; };
我给函数指针起名为Callback
。事实上,当只有一个观察者的时候,观察者模式的机制就等同于回调模式。因此可以认为,回调模式是一种特殊的观察者模式。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。