设计模式之观察者模式(C++)

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

一、观察者模式是什么?

       观察者模式是一种行为型的软件设计模式,定义对象间的一种一对多的依赖关系,当被观察者状态发生改变时,所有观察者都做出相应改变。Qt中的信号与槽就是一种典型的观察者模式。

       观察者模式的优点:

  1. 耦合双方依赖于抽象,不需要了解具体。
  2. 提供了稳定的信息更新传递机制。
  3. 良好扩展性。

      观察者模式的缺点:

  1. 当观察者过多时,挨个通知观察者消息可能会花费较长时间。
  2. 某个观察者出现卡顿,可能影响整个进程,一般采用异步机制解决,但同时也要注意程序安全。

二、观察者模式

2.1 结构图

       客户端即Main主函数,当被观察者发生变化,所有观察者都进行响应。

2.2 代码示例

       场景描述:十字路口汽车等待红绿灯变化。

//Observer.h
/****************************************************/
#pragma once
#include <iostream>
#include <unordered_map>
#include <vector>
#include <list>
#include <string>

using namespace std;

// 抽象观察者
class Observer 
{
public:
	// 构造函数
	Observer(int num):m_number(num){}

	// 更新
    virtual void update(bool flag) = 0;

protected:
	int m_number;
};

// 抽象主题-被观察者
class Subject 
{
public:
	// 连接
    virtual void attach(Observer* observer) = 0;

	// 断连
    virtual void detach(Observer* observer) = 0;

	// 通知
    virtual void notify(bool flag) = 0;

protected:
	vector<Observer*> observers;
};

// 具体主题-红绿灯
class TrafficLight : public Subject
{
public:
	// 连接
	virtual void attach(Observer* observer) {
        observers.push_back(observer);
    }

	// 断连
	virtual void detach(Observer* observer) {
		for (auto iter = observers.begin(); iter != observers.end();){
			if (*iter == observer){
				iter = observers.erase(iter);
			}
			else{
				iter++;
			}
		}
    }

	// 通知
	virtual void notify(bool flag) {
		if (flag) {
			cout << "绿灯通行。" << endl;
			for (auto observer : observers) {
				observer->update(flag);
			}
		}
		else {
			cout << "红灯停止。" << endl;
			for (auto observer : observers) {
				observer->update(flag);
			}
		}
    }

};

// 具体观察者-汽车
class Car : public Observer 
{
public:
	// 构造函数
	Car(int num) :Observer(num) {}

	// 更新
	virtual void update(bool flag) {
		if (flag) {
			cout << m_number << "号汽车:发动。" << endl;
		}
		else {
			cout << m_number << "号汽车:停止。" << endl;
		}
    }
};
//main.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "Observer.h"

using namespace std;

int main() 
{
	// 创建主题对象
	Subject *subject = new TrafficLight();

	// 创建观察者对象
	Observer *observer1 = new Car(1);
	Observer *observer2 = new Car(2);
	Observer *observer3 = new Car(3);
	Observer *observer4 = new Car(4);

	// 连接观察者
	subject->attach(observer1);
	subject->attach(observer2);
	subject->attach(observer3);
	subject->attach(observer4);

	// 绿灯行
	subject->notify(true);

	// 3号车通过,不需要再观察
	subject->detach(observer3);
	cout << "3号车已通过。" << endl;

	// 红灯停
	subject->notify(false);

	// 删除
	delete subject;
	delete observer1;
	delete observer2;
	delete observer3;
	delete observer4;
	subject = nullptr;
	observer1 = nullptr;
	observer2 = nullptr;
	observer3 = nullptr;
	observer4 = nullptr;

	return 0;
}

       程序结果如下。

       红绿灯未亮起绿灯时,有4辆车等候,绿灯通行后,只有3号车通过了,此时3号车不用再观察当前红绿灯状态了,解除绑定;然后红灯亮,其他3辆车继续停车等候。

三、总结

       我尽可能用较通俗的话语和直观的代码例程,来表述我对观察者模式的理解,或许有考虑不周到的地方,如果你有不同看法欢迎评论区交流!希望我举的例子能帮助你更好地理解观察者模式。

       如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

翟天保Steven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值