zoukankan      html  css  js  c++  java
  • 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;
    } 

  • 相关阅读:
    会话管理?
    为什么要用 Dubbo?
    abstract class和interface有什么区别?
    接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?抽象类中是否可以有静态的main方法?
    用最有效率的方法算出2乘以8等於几?
    如何把一段逗号分割的字符串转换成一个数组?
    查看文件内容有哪些命令可以使用?
    使用哪一个命令可以查看自己文件系统的磁盘空间配额 呢?
    Spring框架中的单例bean是线程安全的吗?
    你更倾向用那种事务管理类型?
  • 原文地址:https://www.cnblogs.com/henryliublog/p/10953565.html
Copyright © 2011-2022 走看看