• 21行为型模式之观察者模式


    概念

      Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。

      Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。

    角色和职责

    Subject(被观察者)
             被观察的对象。当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。Subject需要维持(添加,删除,通知)一个观察者对象的队列列表。

    ConcreteSubject
             被观察者的具体实现。包含一些基本的属性状态及其他操作。

    Observer(观察者)
             接口或抽象类。当Subject的状态发生变化时,Observer对象将通过一个callback函数得到通知。

    ConcreteObserver
             观察者的具体实现。得到通知后将完成一些具体的业务逻辑处理。

    典型应用

      - 侦听事件驱动程序设计中的外部事件

      - 侦听/监视某个对象的状态变化

      - 发布者/订阅者(publisher/subscriber)模型中,当一个外部事件(新的产品,消息的出现等等)被触发时,通知邮件列表中的订阅者

    适用于:

             定义对象间一种一对多的依赖关系,使得每一个对象改变状态,则所有依赖于他们的对象都会得到通知。

    案例

    //定义了一种一对多的关系,让多个观察对象(公司员工)同时监听一个主题对象(秘书),主题对象状态发生变化时,会通知所有的观察者,使它们能够更新自己。

    #include <iostream>
    using namespace std;
    #include "vector"
    #include "string"
    
    class Secretary;
    
    //玩游戏的同事类(观察者)
    class PlayserObserver
    {
    public:
    	PlayserObserver(string name, Secretary *secretary)
    	{
    		m_name = name;
    		m_secretary = secretary;
    	}
    	void update(string action)
    	{
    		cout << "观察者收到action:" << action << endl;
    	}
    private:
    	string		m_name;
    	Secretary	*m_secretary;
    };
    
    //秘书类(主题对象,通知者)
    class Secretary
    {
    public:
    	void addObserver(PlayserObserver *o)
    	{
    		v.push_back(o);
    	}
    	void Notify(string action)
    	{
    		for (vector<PlayserObserver *>::iterator it= v.begin(); it!=v.end(); it++ )
    		{
    			(*it)->update(action);
    		}
    	}
    	void setAction(string action)
    	{
    		m_action = action;
    		Notify(m_action);
    	}
    private:
    	string m_action;
    	vector<PlayserObserver *> v;
    };
    
    void main()
    {
    	//subject 被观察者
    	Secretary *s1 = new Secretary;
    
    	//具体的观察者 被通知对象
    	PlayserObserver *po1 = new PlayserObserver("小张", s1);
    	//PlayserObserver *po2 = new PlayserObserver("小李", s1);
    	s1->addObserver(po1);
    	//s1->addObserver(po2);
    	s1->setAction("老板来了");
    	s1->setAction("老板走了");
    	cout<<"hello..."<<endl;
    	system("pause");
    	return ;
    }
    

      

  • 相关阅读:
    LOJ6433 [PKUSC2018] 最大前缀和 【状压DP】
    [NOIP2017] 宝藏 【树形DP】【状压DP】
    51Nod1824 染色游戏 【Lucas定理】【FMT】【位运算】
    51Nod1778 小Q的集合 【组合数】【Lucas定理】
    LOJ6436 [PKUSC2018] 神仙的游戏 【FFT】
    LOJ6432 [PKUSC2018] 真实排名 【组合数】
    BZOJ5210 最大连通子块和 【树链剖分】【堆】【动态DP】
    LOJ2269 [SDOI2017] 切树游戏 【FWT】【动态DP】【树链剖分】【线段树】
    洛谷3707 [SDOI2017] 相关分析 【线段树】
    RBAC
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/10358048.html
Copyright © 2020-2023  润新知