• 【28】c++设计模式——>观察者模式(1)


    观察者模式概念

    C++观察者模式(Observer Pattern)是一种设计模式,它用于在对象之间建立一种一对多的依赖关系。在该模式中,当一个对象(称为主题)发生变化时,所有依赖于它的对象(称为观察者)都会得到通知并自动更新。

    观察者模式通常包含以下几个角色:

    主题(Subject):也称为被观察者或可观察对象,它维护一个观察者列表并提供添加、删除和通知观察者的方法。
    观察者(Observer):定义一个更新接口,使得在主题状态改变时能够得到通知。
    具体主题(ConcreteSubject):实现主题接口,具体主题对象在状态变化时通知观察者。
    具体观察者(ConcreteObserver):实现观察者接口,具体观察者对象在接收到通知后进行相应的更新操作。

    在C++中实现观察者模式可以使用以下步骤:

    (1)定义主题接口 Subject,包括添加观察者、删除观察者和通知观察者的方法。
    (2)定义观察者接口 Observer,包括更新方法。
    (3)实现具体主题类 ConcreteSubject,维护观察者列表,实现添加观察者、删除观察者和通知观察者的方法。
    (4)实现具体观察者类 ConcreteObserver,实现更新方法。
    (5)在使用时,创建具体主题对象和具体观察者对象,并将观察者注册到主题中。
    当具体主题对象的状态发生变化时,他会变量观察者列表,调用观察者的更新方法,从而实现观察者模式的效果。这样观察者就能根据主题的状态进行相应的操作,实现对象之间的松耦合关系。
    观察者也叫订阅者,主题也叫发布者,谁发布,谁订阅,发布者维护一个订阅者列表,想订阅的人被添加到该列表中,每当要发布消息时,发布者就会轮询这个列表,订阅者就会收到消息。

    实例代码

    #include
    #include
    using namespace std;
    
    //抽象观察者接口
    class Observer
    {
    public:
    	virtual void recive(int data) = 0; //订阅者的接受方法,用来接受发布者消息
    };
    
    //具体订阅者A
    class ConcreteObserverA : public Observer
    {
    public:
    	void recive(int data) override
    	{
    		cout << "i am A,i accept data:" << data << endl;
    	}
    };
    
    //具体订阅者A
    class ConcreteObserverB : public Observer
    {
    public:
    	void recive(int data) override
    	{
    		cout << "i am B,i accept data:" << data << endl;
    	}
    };
    
    //抽象发布者
    class Subscribe
    {
    public:
    	virtual void attach(Observer* observer) = 0; //添加观察者,将观察者添加到列表中,纯虚函数
    	virtual void detach(Observer* observer) = 0; //删除观察者,将观察者从列表中删除,纯虚函数
    	virtual void notify(int data) = 0; //通知观察者
    };
    
    //具体发布者
    class SubscribeS : public Subscribe
    {
    private:
    	vector<Observer*> observers; //存储观察者列表
    public:
    	void attach(Observer* observer) override//添加观察者,将观察者添加到列表中,纯虚函数
    	{
    		observers.push_back(observer);
    	}
    
    	void detach(Observer* observer) //删除观察者,将观察者从列表中删除,纯虚函数
    	{
    		for (auto &it : observers)
    		{
    			auto it = std::find(observers.begin(), observers.end(), observer);
    			if (it != observers.end())
    			{
    				observers.erase(it);
    			}
    		}
    	}
    	void notify(int data) //通知观察者
    	{
    		for (auto& it : observers)
    		{
    			it->recive(data);
    		}
    	}
    };
    
    int main()
    {
    	SubscribeS s;
    	ConcreteObserverA a;
    	ConcreteObserverB b;
    	s.attach(&a);
    	s.attach(&b);
    
    	s.notify(123456);
    
    	s.detach(&b);
    	s.notify(33333333333333333);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    在这里插入图片描述

  • 相关阅读:
    测试用例千万不能随便,记录由一个测试用例异常引起的思考
    Java随笔-Socket
    linux创建sftp用户
    13基于PCA的人脸识别,程序已调通,可将自己的数据替换进行识别,得到识别准确率结果,MATLAB平台。
    【故障公告】1个存储过程拖垮整个数据库
    Python数组基本操作
    简单工厂模式 和 工厂方法 和 抽象工厂的区别
    Jenkins的一些记录
    c语言 char* 和char[]的返回值
    Swift 5.9 有哪些新特性(二)
  • 原文地址:https://blog.csdn.net/weixin_42097108/article/details/133975109