• 观察者模式


    #include
    #include //for smart pointer
    #include <unordered_map> //for unordered_map
    #include

    using namespace std;

    class Widget
    {
    public:
        Widget(int id):ID(id){}
        
        int ID;
    };

    //1. 利用weak_ptr来缓存对象
    //模拟从数据库中加载,并创建shared_ptr指向widget对象
    shared_ptr loadWidget(int WidgetID)
    {
        return make_shared(WidgetID); 
    }

    //带缓存的工厂函数
    std::shared_ptr fastloadWidget(int WidgetID) //返回shared_ptr类型
    {
        //缓存:weak_ptr类型
        static std::unordered_map> cache;

        auto objPtr = cache[WidgetID].lock(); //objPtr的类型为shared_ptr,指向缓存的对象

        if (!objPtr) { //如果对象不在缓存中. 这里省略了缓存中因失效而不断累积std::weak_ptr的处理。
            objPtr = loadWidget(WidgetID);
            cache[WidgetID] = objPtr;
        }

        return objPtr;
    }

    //2. 观察者模式
    //2.1 观察者
    class WeatherObservers //抽象观察者
    {
    public:
        virtual void updateWeatherInfo(int num) = 0;
    };
    //机场:具体观察者
    class Airport : public WeatherObservers
    {
    public:
        void updateWeatherInfo(int num) override
        {
            std::cout <<"Airport: " << num << endl;
        }
    };
    //学校:具体观察者
    class School : public WeatherObservers
    {
    public:
        void updateWeatherInfo(int num) override
        {
            std::cout << "School: " << num << endl;
        }
    };

    //2.1 主题(气象站)
    class WeatherStation
    {
        using ObserverPtr = std::weak_ptr; //弱引用

        //set集合中保存观察者的弱引用(以ObserverPtr为关键字,基于ownership排序)
        using ObserverList = std::set>;

        ObserverList obs; //保存所有观察者
    public:
        //注册观察者
        void registerObserver(const ObserverPtr oPtr)
        {
            if (obs.find(oPtr) == obs.end()) {
                obs.insert(oPtr);
            }
        }
        //注销观察者
        void unregisterObserver(const ObserverPtr oPtr) //oPtr为weak_ptr类型
        {
            if (obs.find(oPtr) != obs.end())
            {
                obs.erase(oPtr);
            }
        }

        //通知各个观察者
        void notifyObservers(int num)
        {
            std::shared_ptr tempPtr;
            for (auto& ob : obs)
            {
                if ((tempPtr = ob.lock())) {
                    tempPtr->updateWeatherInfo(num);
                }
            }
        }
    };


    int main()
    {
        //观察者模式
        WeatherStation station;
        std::shared_ptr airport(new Airport());
        std::shared_ptr  school(new School());

        station.registerObserver(airport);
        station.registerObserver(school);

        station.notifyObservers(1);

        station.unregisterObserver(school);
        station.notifyObservers(2);

        return 0;
    }
    /*输出结果
    Airport: 1
    School: 1
    Airport: 2
    */

  • 相关阅读:
    docker创建镜像仓库及配置
    深入解析React DnD拖拽原理,轻松掌握拖放技巧!
    EDA国产化之路,路在何方?
    【网络安全】beef-xss实操以及xss修复方案
    深度学习——(9)神经网络参数详解
    【JavaScript】深入浅出理解事件循环
    Vue的模板语法
    【板栗糖GIS】三维建模—倾斜航飞OSGB数据可以转成skp模型输出吗?
    java日志框架之Logback和Log4j2
    编程界也有修仙秘籍?程序员码字3年终得《JavaScript 百炼成仙》
  • 原文地址:https://blog.csdn.net/u012983289/article/details/132896750