观察者模式
QT中的信号和槽机制就相当于观察者模式的一种扩展,全局实现了观察者模式,如果对QT的信号槽机制很了解的话对于观察者模式应该得心应手,因为信号和槽机制实现起来比观察者模式难得多(我说的不是简单的connect这样子…)
什么是观察者模式?
就是当目标发送了某个信号后与其绑定的对象执行特定的动作。就类似于开关和灯的关系,开关发送通电信号,灯观察到了这个信号后执行亮灯动作。所以开关是被观察的目标,灯是观察者。
首先明确一点,使用这个模式的目的是什么?
假设我是一名嵌入式工程师,我需要编写一个开关类,当开关类中的一个位置被置1的时候,通知所有插在这个开关上的设备都通电。
不使用观察者模式的实现
在开关类中设置一个bool flag同时开关类作为全局对象,所有的设备类都去循环检查这个值,如果为真就执行对应的动作。(最简单的实现)
- 优点:简单毫不做作
- 缺点:无形之中浪费很多性能,我需要在一个线程中不断的去检查这个值,直到flag置为1的时候才需要触发对应的动作(通电)。团队开发的时候全局变量很容易出问题,经常被某某某给乱用就用出问题了。
观察者模式
首先明确一个观察者:“设备”,被观察的“目标”:开关。class 开关 { //开关类的代码 public:void 按下开关(); private 设备[数量]; }
按下开关这个函数需要执行的动作是设备通电后需要执行的动作(函数)
二者被绑定到了一起,这样下来只要调用按下开关()
这个函数就好了。 - 优点:整体逻辑感强,易于维护,性能好
- 缺点:写的有点麻烦
这样就实现了最简单的观察者模式。
接下来我们将问题扩大,当这个开关是各种各样的,设备所绑定的开关也是各种各样的,我们如果去每个都这么写一下代码量就很大,冗余也很多。那么我们可以将开关类抽象成一个目标类,实现如下:
class Target
{
public :
Target();
~Target();
void sendSignal()=0; //发送信号部分,具体怎么轮询调用容器中的观察者动作需要自己写
void addObserver(); //添加观察者到容器中
void delObserver(); //删除
protected:
vector<Observer>Observers; //这个需要受保护,不能开放给外部肆意修改
};
class Observer
{
public:
Observer();
~Observer();
type Signalfun(argv)=0; //获得信号后的动作。
}
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment