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;  //获得信号后的动作。
	
	
}