zoukankan      html  css  js  c++  java
  • 设计模式C++学习笔记之十六(Observer观察者模式)

    概念:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

    main(),

    IObservable,被观察者接口

    CHanFeiZiObservable,被观察者韩非子

    IObserver,观察者接口

    CLiSiObserver,观察者李斯

    CZhouSiObserver观察者周斯

    说明:将观察者聚集到被观察者韩非子身边,韩非子的每一个举动都会通知给观察者,如李斯或周斯。

    注意:最多允许一个对象既是观察者也是被观察者。就像数据库中的触发器一样,成为一个复杂的链就很难维护了。观察者类似于委托的处理方式。

    //IObservable.h

    #pragma once
    #include "IObserver.h"
    #include <iostream>
    using std::string;
    class IObservable
    {
    public:
        IObservable(void)
        {
        }
        virtual ~IObservable(void)
        {
        }
        virtual void AddObserver(IObserver *pObserver) = 0;
        virtual void DeleteObserver(IObserver *pObserver) = 0;
        virtual void NotifyObservers(string context) = 0;
    };

    //HanFeiziObservable.h

    #pragma once
    #include "iobservable.h"
    #include "IObserver.h"
    #include <vector>
    using std::vector;
    class CHanFeiziObservable :
        public IObservable
    {
    public:
        CHanFeiziObservable(void);
        ~CHanFeiziObservable(void);
        void AddObserver(IObserver *pObserver);
        void DeleteObserver(IObserver *pObserver);
        void NotifyObservers(string context);
        void HaveBreakfast();
        void HaveFun();
    private:
        vector<IObserver*> m_observerList;
        typedef vector<IObserver*>::const_iterator ObserverList_C_iterator;
    };

    //HanFeiziObservable.cpp

    #include "StdAfx.h"
    #include "HanFeiziObservable.h"
    #include <iostream>
    using std::string;
    using std::cout;
    using std::endl;
    CHanFeiziObservable::CHanFeiziObservable(void)
    {
    }
    CHanFeiziObservable::~CHanFeiziObservable(void)
    {
    }
    void CHanFeiziObservable::AddObserver( IObserver *pObserver )
    {
        m_observerList.push_back(pObserver);
    }
    void CHanFeiziObservable::DeleteObserver( IObserver *pObserver )
    {
        ObserverList_C_iterator it = m_observerList.begin();
        for (; it != m_observerList.end(); it++)
        {
            string name = (*it)->GetName();
            if (name.compare(pObserver->GetName()) == 0)
            {
                //找到了删除。
            }
        }
    }
    void CHanFeiziObservable::NotifyObservers( string context )
    {
        ObserverList_C_iterator it = m_observerList.begin();
        for (; it != m_observerList.end(); it ++)
        {
            (*it)->Update(context);
        }
    }
    void CHanFeiziObservable::HaveBreakfast()
    {
        cout << "韩非子:开始吃饭了..." << endl;

        this->NotifyObservers("韩非子在吃饭");
    }
    void CHanFeiziObservable::HaveFun()
    {
        cout << "韩非子:开始娱乐了..." << endl;

        this->NotifyObservers("韩非子在娱乐");
    }
    //IObserver.h

    #pragma once
    #include <iostream>
    using std::string;
    class IObserver
    {
    public:
        IObserver(string _name)
        {
            this->m_name = _name;
        }
        virtual ~IObserver(void)
        {
        }
        virtual void Update(string context) = 0;
        virtual string GetName() = 0;//为c++单独增加的函数,用于删除时查找观察者。
    protected:
        string m_name;
    };

    //LiSiObserver.h

    #pragma once
    #include "iobserver.h"
    #include <iostream>
    using std::string;
    class CLiSiObserver :
        public IObserver
    {
    public:
        CLiSiObserver(void);
        ~CLiSiObserver(void);
        void Update(string context);
        string GetName();
    private:
        void ReportToQinShiHuang(string report);
    };

    //LiSiObserver.cpp

    #include "StdAfx.h"
    #include "LiSiObserver.h"
    #include <iostream>
    using std::cout;
    using std::endl;
    using std::string;
    CLiSiObserver::CLiSiObserver(void) : IObserver("李斯")
    {
    }
    CLiSiObserver::~CLiSiObserver(void)
    {
    }
    void CLiSiObserver::Update( string context )
    {
        cout << "李斯:观察到韩非子活动,开始向老板汇报了..." << endl;
        this->ReportToQinShiHuang(context);
        cout << "李斯:汇报完毕,秦老板赏给他两个萝卜吃吃..." << endl;
    }
    void CLiSiObserver::ReportToQinShiHuang( string report )
    {
        cout << "李斯:报告,秦老板!韩非子有活动了--->" << report.c_str() << endl;
    }
    string CLiSiObserver::GetName()
    {
        return m_name;
    }
    //ZhouSiObserver.h

    #pragma once
    #include "iobserver.h"
    #include <iostream>
    using std::string;
    class CZhouSiObserver :
        public IObserver
    {
    public:
        CZhouSiObserver(void);
        ~CZhouSiObserver(void);
        void Update(string context);
        string GetName();
    private:
        void Cry(string report);
    };

    //ZhouSiObserver.cpp

    #include "StdAfx.h"
    #include "ZhouSiObserver.h"
    #include <iostream>
    using std::cout;
    using std::endl;
    using std::string;
    CZhouSiObserver::CZhouSiObserver(void) : IObserver("周斯")
    {
    }
    CZhouSiObserver::~CZhouSiObserver(void)
    {
    }
    void CZhouSiObserver::Update( string context )
    {
        cout << "周斯:观察到韩非子活动,自己也开始活动了..." << endl;
        this->Cry(context);
        cout << "周斯:真真的哭列了..." << endl;
    }
    void CZhouSiObserver::Cry( string report )
    {
        cout << "周斯:为因" << report.c_str() << ", ————所以我悲伤呀!" << endl;
    }
    string CZhouSiObserver::GetName()
    {
        return m_name;
    }

    // Observer.cpp 
    #include "stdafx.h"
    #include "HanFeiZi.h"
    #include "LiSi.h"
    #include "HanFeiZiNew.h"
    #include "HanFeiziObservable.h"
    #include "LiSiObserver.h"
    #include "ZhouSiObserver.h"
    #include <iostream>
    using std::cout;
    using std::endl;
    using std::string;

    void DoNew()
    {
        //IHanFeiZi.h, HanFeiZiNew.h, ILiSi.h, LiSi.h
       // cout << "----------用新的方法试试----------" << endl;

        //CHanFeiZiNew hanfeizi;

        //hanfeizi.HaveBreakfast();

        //hanfeizi.HaveFun();
    }


    void DoNewNew()
    {
        //IObservable.h, HanfeiziObservable.h, IObserver.h, LiSiObserver.h
        cout << "----------用更新的方法再试试----------" << endl;
        IObserver *pLiSi = new CLiSiObserver();
        IObserver *pZhouSi = new CZhouSiObserver();

        CHanFeiziObservable *pHanFeiZi = new CHanFeiziObservable();

        pHanFeiZi->AddObserver(pLiSi);
        pHanFeiZi->AddObserver(pZhouSi);
        pHanFeiZi->HaveBreakfast();

        delete pLiSi;
        pLiSi = NULL;
        delete pHanFeiZi;
        pHanFeiZi = NULL;
    }


    int _tmain(int argc, _TCHAR* argv[])
    {
        //比较原始的方法,用线程来观察。
        //DoIt();

        //把李斯这个类聚集到韩非子这个类上,这样的话耦合度太高了,还是用更抽象的方式。
        DoNew();

        //更抽象的方式,想要观察韩非子的人多了去了,不可能只允许李斯观察。
        DoNewNew();


        _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
        _CrtDumpMemoryLeaks();
        return 0;
    }

     
  • 相关阅读:
    Open-E DSS V7 应用系列之 9 主动/主动 iSCSI群集部署
    Open-E DSS V7 应用系列 7~8
    Open-E DSS V7 应用系列之4~6
    Open-E DSS V7 应用系列之1~3
    kbmmw 5.18.0 发布
    Spring笔记--@ConditionalOnBean坑
    Kafka 3.0新特性
    如何让Git记住你的GitHub Token,避免每次都要重复输入?
    特征值和特征向量到底是个啥?能做什么用?
    ICCV 2021 | BN-NAS: 只训练BN层来自动搜索模型
  • 原文地址:https://www.cnblogs.com/mfryf/p/2465028.html
Copyright © 2011-2022 走看看