• c++11优化观察者模式


    1. 观察者模式,一般是通过c++继承强耦合关系来实现的,代码如下:

    interface.h

    #ifndef EFWEIFOWEJOFWOEFJWOEF_h
    #define EFWEIFOWEJOFWOEFJWOEF_h
    #include <iostream>
    #include <list>
    using namespace std;

    class Observer
    {
    public:
        virtual void Update(int) = 0;
    };

    class Subject
    {
    public:
        virtual void Attach(Observer *) = 0;
        virtual void Detach(Observer *) = 0;
        virtual void Notify() = 0;
    };

    #endif

    observe.h

    #include "interface.h"
    class ConcreteObserver : public Observer
    {
    public:
        ConcreteObserver(Subject *pSubject) : m_pSubject(pSubject){}

        void Update(int value)
        {
            cout << "ConcreteObserver get the update. New State:" << value << endl;
        }

    private:
        Subject *m_pSubject;
    };

    class ConcreteObserver2 : public Observer
    {
    public:
        ConcreteObserver2(Subject *pSubject) : m_pSubject(pSubject){}

        void Update(int value)
        {
            cout << "ConcreteObserver2 get the update. New State:" << value << endl;
        }

    private:
        Subject *m_pSubject;
    };

    subject.h

    #ifndef FOWEJWEIFOWEFJWEOFJWFJWJFWEFIWOEFWEWF_H
    #define FOWEJWEIFOWEFJWEOFJWFJWJFWEFIWOEFWEWF_H
    #include "interface.h"

    class ConcreteSubject : public Subject
    {
    public:
        void Attach(Observer *pObserver);
        void Detach(Observer *pObserver);
        void Notify();

        void SetState(int state)
        {
            m_iState = state;
        }

    private:
        std::list<Observer *> m_ObserverList;
        int m_iState;
    };
    #endif

    subject.cpp

    #include "subject.h"

    void ConcreteSubject::Attach(Observer *pObserver)
    {
        m_ObserverList.push_back(pObserver);
    }

    void ConcreteSubject::Detach(Observer *pObserver)
    {
        m_ObserverList.remove(pObserver);
    }

    void ConcreteSubject::Notify()
    {
        std::list<Observer *>::iterator it = m_ObserverList.begin();
        while (it != m_ObserverList.end())
        {
            (*it)->Update(m_iState);
            ++it;
        }
    }

    main.cpp

    #include "subject.h"

    #include "observe.h"

    int main()
    {
        // Create Subject
        ConcreteSubject *pSubject = new ConcreteSubject();

        // Create Observer
        Observer *pObserver = new ConcreteObserver(pSubject);
        Observer *pObserver2 = new ConcreteObserver2(pSubject);

        // Change the state
        pSubject->SetState(2);

        // Register the observer
        pSubject->Attach(pObserver);
        pSubject->Attach(pObserver2);

        pSubject->Notify();

        // Unregister the observer
        pSubject->Detach(pObserver);

        pSubject->SetState(3);
        pSubject->Notify();

        delete pObserver;
        delete pObserver2;
        delete pSubject;
            return 0;
    }

    编译:

    g++ interface.h subject.h observe.h subject.cpp main.cpp -std=c++11 -o test

    ./test

    ConcreteObserver get the update. New State:2
    ConcreteObserver2 get the update. New State:2
    ConcreteObserver2 get the update. New State:3

    2. 用C++11 改进观察者模式

    #include <iostream>
    #include <functional>
    #include <string>
    #include <map>
    #include <algorithm>
    using namespace std;

    class NonCopyable
    {
    protected:
            NonCopyable() = default;
            ~NonCopyable() = default;
            NonCopyable(const NonCopyable&) = delete;
            NonCopyable& operator= (const NonCopyable&) = default;
    };

    template <typename Func>
    class Events : public NonCopyable
    {
    public:
            Events(){}
            ~Events(){}

            //注册观察者, 支持右值引用
            int Connect(Func&& f){
                    return Assign(f);
            }

            //注册观察者
            int Connect(Func& f){
                    return Assign(f);
            }

            //移除观察者
            void Disconnect(int key){
                    m_connections.erase(key);
            }

            //通知所有的观察者
            template <typename... Args>
            void Notify(Args&& ... args){
                    for(auto& it : m_connections){
                            it.second(std::forward<Args>(args)...);
                    }
            }

    private:
            //保存观察者并分配观察者的编号
            template <typename F>
            int Assign(F&& f){
                    int k = m_observerId++;
                    m_connections.emplace(k, std::forward<F>(f));
                    return k;
            }

    private:
            int m_observerId = 0;   //观察者编号

           std::map<int, Func> m_connections;      //观察者列表

    };

    struct stA
    {
            int a;
            int b;
            void printstA(int a, int b){ std::cout << a << ", " << b << std::endl; }
    };

    struct print
    {
            print& operator()(int a, int b){
                    std::cout << a << ", " << b << std::endl;
            }
    };

    int main()
    {
            Events<std::function<void(int, int)> > myevent;
            auto key = myevent.Connect(print());

            stA t;
            auto lambdakey = myevent.Connect([&t](int a, int b){ t.a = a; t.b = b; } );


            //std::function 注册
            std::function<void(int, int)> f = std::bind(&stA::printstA, &t, std::placeholders::_1, std::placeholders::_2);
            myevent.Connect(f);

            int a =1, b =2;
            myevent.Notify(a,b);
            myevent.Disconnect(key);

            return 0;
    } 

  • 相关阅读:
    读书笔记之理想设计的特征
    一些javascript 变量声明的 疑惑
    LINQ 使用方法
    Google MySQL tool releases
    读书笔记之设计的层次
    EF之数据库连接问题The specified named connection is either not found in the configuration, not intended to be used with the Ent
    转载 什么是闭包
    javascript面向对象起步
    Tips
    数据结构在游戏中的应用
  • 原文地址:https://www.cnblogs.com/henryliublog/p/10953565.html
Copyright © 2020-2023  润新知