• 第十四章-观察者模式


    观察者模式: 观察者模式又叫做发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。

    图片

    基本代码

    #include<iostream>
    #include<string>
    #include<vector>
    
    using namespace std;
    
    class Observer
    {
    public:
    	virtual void Update() = 0;
    };
    
    class Subject
    {
    private:
    	vector<Observer*> observers;
    
    public:
    	void Attach(Observer* observer_t)
    	{
    		observers.push_back(observer_t);
    	}
    
    	void Detach(Observer* observer_t)
    	{
    		for (auto _i = observers.begin(); _i != observers.end(); _i++)
    		{
    			if (*_i == observer_t)
    			{
    				observers.erase(_i);
    				break;
    			}				
    		}
    	}
    
    	void Notify()
    	{
    		for (auto _i : observers)
    			_i->Update();
    	}
    
    };
    
    class ConcreteSubject : public Subject
    {
    private:
    	string subjectState;
    
    public:
    	string get() { return subjectState; }
    	void set(string subjectState_t) { subjectState = subjectState_t; }
    };
    
    class ConcreteObserver :public Observer
    {
    private:
    	string name;
    	string observerState;
    	ConcreteSubject* subject;
    
    public:
    	ConcreteObserver(ConcreteSubject* subject_t, string name_t)
    	{
    		subject = subject_t;
    		name = name_t;
    	}
    
    	void Update()
    	{
    		observerState = subject->get();
    		cout << "观察者" << name << "的新状态时" << observerState << endl;
    	}
    
    	ConcreteSubject* get() { return subject; }
    	void set(ConcreteSubject* subject_t) { subject = subject_t; }
    };
    
    
    int main()
    {
    	ConcreteSubject* s = new ConcreteSubject();
    
    	s->Attach(new ConcreteObserver(s, "X"));
    	s->Attach(new ConcreteObserver(s, "Y"));
    	s->Attach(new ConcreteObserver(s, "Z"));
    
    	s->set("ABC");
    	s->Notify();
    
    	system("pause");
    	return 0;
    }
    
    
    

    图片

    老板回来了代码示例

    #include<iostream>
    #include<string>
    #include<vector>
    
    using namespace std;
    
    class Subject;
    
    class Observer
    {
    protected:
    	string name;
    	Subject* sub;
    public:
    	Observer(string name_t, Subject* sub_t)
    	{
    		name = name_t;
    		sub = sub_t;
    	}
    	virtual void Update() = 0;
    };
    
    class Subject
    {
    public:
    	string subjectState;
    	virtual void Attach(Observer* observer_t) = 0;
    	virtual void Detach(Observer* observer_t) = 0;
    	virtual void Notify() = 0;
    	virtual string getsubjectState() = 0;
    	virtual void setsubjectState(string subjectState_t) = 0;
    
    };
    
    class Boss :public Subject
    {
    private:
    	vector<Observer*> observers;
    	string action;
    
    public:
    	void Attach(Observer* observer_t)
    	{
    		observers.push_back(observer_t);
    	}
    
    	void Detach(Observer* observer_t)
    	{
    		for (auto _i = observers.begin(); _i != observers.end(); _i++)
    		{
    			if (*_i == observer_t)
    			{
    				observers.erase(_i);
    				break;
    			}
    		}
    	}
    
    	void Notify()
    	{
    		for (auto _i : observers)
    			_i->Update();
    	}
    
    	string getsubjectState() { return subjectState; }
    	void setsubjectState(string subjectState_t) { subjectState = subjectState_t; }
    };
    
    class Secretary :public Subject
    {
    private:
    	vector<Observer*> observers;
    	string action;
    
    public:
    	void Attach(Observer* observer_t)
    	{
    		observers.push_back(observer_t);
    	}
    
    	void Detach(Observer* observer_t)
    	{
    		for (auto _i = observers.begin(); _i != observers.end(); _i++)
    		{
    			if (*_i == observer_t)
    			{
    				observers.erase(_i);
    				break;
    			}
    		}
    	}
    
    	void Notify()
    	{
    		for (auto _i : observers)
    			_i->Update();
    	}
    
    	string getsubjectState() { return subjectState; }
    	void setsubjectState(string subjectState_t) { subjectState = subjectState_t; }
    };
    
    class StockObserver :public Observer
    {
    public:
    	StockObserver(string name_t, Subject* sub_t)
    		: Observer(name_t, sub_t)
    	{
    
    	}
    
    	void Update()
    	{ 
    		cout << sub->getsubjectState() << " " << name << " 关闭股票行情,继续工作!" << endl;
    	}
    };
    
    class NBAObserver :public Observer
    {
    public:
    	NBAObserver(string name_t, Subject* sub_t)
    		: Observer(name_t, sub_t)
    	{
    
    	}
    
    	void Update()
    	{
    		cout << sub->getsubjectState() << " " << name << " 关闭NBA直播,继续工作!" << endl;
    	}
    };
    
    
    
    int main()
    {
    	Boss* huhansan = new Boss();
    	StockObserver* tongshi1 = new StockObserver("魏", huhansan);
    	NBAObserver* tongshi2 = new NBAObserver("易", huhansan);
    
    	huhansan->Attach(tongshi1);
    	huhansan->Attach(tongshi2);
    
    	huhansan->Detach(tongshi1);
    
    	huhansan->setsubjectState("我胡汉三回来了!");
    
    	huhansan->Notify();
    
    
    	system("pause");
    	return 0;
    }
    
    

    观察者模式的特点

    总的来讲,观察者模式所做的工作其实就是在解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化。

    事件委托

    ....................

  • 相关阅读:
    表字符集与存储过程字符集不一致导致的存储过程执行缓慢
    自动类型转换与强制类型转换
    集合中的对象与引用
    54. 螺旋矩阵
    [算法] 二分查找(C++)
    [MySQL优化] 需要创建索引和不要创建索引的情况
    [Spring Cloud] Nacos注册中心服务分组
    mysql导入大sql文件
    [Spring Security] 前后端分离项目中后端登录代码的简单示例
    URL中含特殊字符传参
  • 原文地址:https://www.cnblogs.com/wfcg165/p/12012973.html
Copyright © 2020-2023  润新知