• 设计模式之观察者模式(Observer Pattern)


      定义:定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖它的对象都会得到通知并被自动刷新,也称为发布-订阅模式(Publish-Subscribe Pattern)。

      优点:1、观察者和被观察者是抽象耦合

           2、建立一套触发机制

      缺点:1、一个被观察者,多个观察者,开发和调试都变得相当复杂

         2、一个观察者卡壳,会影响整体执行效率

         3、需要考虑多级触发的效率问题

    using namespace std;
    
    //观察者基类
    class abstractObserver
    {
    public:
        abstractObserver() {}
        virtual ~abstractObserver() {}
        
        virtual void Update() = 0;
    };
    
    //花园里的:白菜基类
    class abstractBaicai
    {
    public:
        abstractBaicai(string name, bool needWater)
        {
            this->name = name;
            this->needWater = needWater;
        }
        virtual ~abstractBaicai() 
        {
            //析构释放
            while (!camera.empty()) 
            {
                camera.erase(camera.begin());
            }
        }
    
        ////白菜是否需要浇水
        virtual void water() 
        {
            if (this->needWater == true)
            {
                printf("需要浇水!
    ");
            }
            else
            {
                printf("不需要浇水了!
    ");
            }
        };
    
        void Attach(abstractObserver *observer) { camera.push_back(observer); }     //添加观察者  
        void Remove(abstractObserver *observer) { camera.remove(observer); }        //移除观察者 
        //通知观察者  
        void Notify() 
        {
            list<abstractObserver*>::iterator iter = camera.begin();
            for (; iter != camera.end(); iter++) 
            {
                (*iter)->Update();
                this->water();
            }
                
        }
        //状态设置
        virtual void SetStatus(bool needWater) { this->needWater = needWater; }
        
        //白菜名
        string name;
    protected:
        //是否需要浇水
        bool needWater;
    private:
    
        //花园里有很多摄像头(观察者)
        list<abstractObserver*> camera;
    };
    
    //观察者实例:摄像头
    class camera : public abstractObserver
    {
    public:
        camera(abstractBaicai *pBaicai, string name) 
        {
            m_Baicai = pBaicai;
            this->name = name;
    
            //白菜注册摄像头
            m_Baicai->Attach(this);
        }
        ~camera() { delete m_Baicai; }
        void Update() 
        {
            cout << name << "捕捉到改变:"<<m_Baicai->name;
        }
    
    private:
        //观察对象:白菜
        abstractBaicai *m_Baicai;
        //摄像头名字
        string name;
    };
    
    
    //被观察实例:大白菜
    class bigBaicai : public abstractBaicai
    {
    public:
        bigBaicai(string name, bool needWater):abstractBaicai(name ,needWater){}
        ~bigBaicai() {}
        //状态设置
        void SetStatus(bool needWater) 
        {
            if (this->needWater != needWater)
            {
                this->needWater = needWater;
                this->Notify();
            }
        }
    };
    
    int main() 
    {
        //初始状态:不需要浇水
        abstractBaicai *Baicai = new bigBaicai("一号大白菜",false);
    
        //一号摄像头监控大白菜
        abstractObserver *camera1 = new camera(Baicai,"一号摄像头");
    
        //二号摄像头监控大白菜
        abstractObserver *camera2 = new camera(Baicai, "二号摄像头");
    
        //三号摄像头监控大白菜
        abstractObserver *camera3 = new camera(Baicai, "三号摄像头");
    
        //状态改变:需要浇水
        Baicai->SetStatus(true);
        
        //析构函数里面所有监控都被释放,只需要delete被观察者即可
        delete Baicai;
    }
    既然选择了远方,便只顾风雨兼程
  • 相关阅读:
    Mosquitto搭建Android推送服务(一)MQTT简介
    Quartz定时任务简单实例
    Oracle基础知识(一)、简介与安装
    [2013-08-01]window.open
    C#中DataTable与泛型集合互转(支持泛型集合中对象包含枚举)
    C#代码安装Windows服务(控制台应用集成Windows服务)
    Node+Socket实现聊天室
    web前端架构
    Laravel-admin form 表单是增加或者修改
    Laravel-admin 消息提醒、播放音频、点击跳转
  • 原文地址:https://www.cnblogs.com/Forever-Road/p/6601115.html
Copyright © 2020-2023  润新知