• 观察者模式(C++实现)


    观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象,在主题对象的状态发生变化时,会通知所有的观察者。

    观察者模式角色如下:
    
    抽象主题(Subject)角色:抽象主题角色提供维护一个观察者对象集合的操作方法,对集合的增加、删除等。
    具体主题(ConcreteSubject)角色:将有关状态存入具体的观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发通知。具体主题角色负责实现抽象主题中的方法。
    抽象观察者(Observer)角色:为具体观察者提供一个更新接口。
    具体观察者(ConcreteObserver)角色:存储与主题相关的自洽状态,实现抽象观察者提供的更新接口。

     Case:

    在教室里老师还没有来,同学都在干着各的事情,小张正在打游戏,小李正在抄作业.....,  现在同学们要求班长当卧底,监视老师,当老师来了通知大家一声。然后打游戏的马上停止,抄作业的也停止。

    这里班长相当于是一个通知者, 小张、小李,以及其他同学显然是监听者,他们监听了班长那的消息,一旦老师来了马上采取相关的行动。

    首先,先把通知者的行为抽象为一个接口:(subject)

    class INotifier
    {
    public:
        virtual void registerListenner(ITeacherListenner *l) =0 ;
        virtual void removeListenner(ITeacherListenner *l) =0 ; 
        virtual void notify() =0 ;    
    };

    第二,然后班长作为一个具体的通知者:(ConcreteSubject)

    class MonitorNotifier:public INotifier
    {
    public:
        void registerListenner(ITeacherListenner *l)
        {
            listenners.push_back(l);
        }
    void removeListenner(ITeacherListenner *l) { list<ITeacherListenner*>::iterator it; for(it=listenners.begin();it!=listenners.end();it++) { if(*it == l) { listenners.remove(l); break; } } }
    void notify() { list<ITeacherListenner*>::iterator it; for(it=listenners.begin();it!=listenners.end();it++) { (*it)->onTecherComming(mValue;);
         }
    }

        void setValue(int value)
    {
         mValue = value;
         notify();
        }
    private: 
      
    list<ITeacherListenner*> listenners;
      int mValue;
    };

    第三, 定义一个监听者的接口,想要监听老师来了这个消息的同学必须要实现这个接口:

    class ITeacherListenner
    {
    public:
        virtual void onTecherComming(int value) = 0; 
    };

    第四,ZhangSan 和 LiSi 监听了老师来了这个接口:

    class ZhangSan:public ITeacherListenner
    {
    public:
        void onTecherComming(int value)
        {
            stopCopyWork(value);
        }
        
        void stopCopyWork(int value)
        {
            cout<<"zhangsan stopCopyWork + "<<value<<endl;
        }
    };
    
    class LiSi:public ITeacherListenner
    {
    public:
        void onTecherComming(int value)
        {
            stopPlayGame(value);
        }
        void stopPlayGame(int value)
        {
            cout<<"lisi stopPlayGame + "<<value<<endl;
        }
    };
    int main()
    {
       cout << "Hello World1-------------"<<endl;
       MonitorNotifier monitor;
       ZhangSan zs;
       LiSi ls;
       monitor.registerListenner(&zs);
       monitor.registerListenner(&ls);
       monitor.setValue(1);
        
       cout << "Hello World2-------------"<<endl;
       monitor.removeListenner(&ls);
       monitor.setValue(2);
        
       return 0;
    }

    运行结果如下:

    Hello World1-------------
    zhangsan stopCopyWork + 1
    lisi stopPlayGame + 1
    Hello World2-------------
    zhangsan stopCopyWork + 2

    最后:完整的Demo(下载后删掉.sh)

  • 相关阅读:
    [Erlang 0106] Erlang实现Apple Push Notifications消息推送
    一场推理的盛宴
    [Erlang 0105] Erlang Resources 小站 2013年1月~6月资讯合集
    [Erlang 0104] 当Erlang遇到Solr
    [Erlang 0103] Erlang Resources 资讯小站
    history.go(-1)和History.back()的区别
    [Java代码] Java用pinyin4j根据汉语获取各种格式和需求的拼音
    spring中context:property-placeholder/元素
    Java中的异常处理:何时抛出异常,何时捕获异常?
    用Jersey构建RESTful服务1--HelloWorld
  • 原文地址:https://www.cnblogs.com/yangjj08/p/10533250.html
Copyright © 2020-2023  润新知