C++设计模式行为型之观察者模式

一、概述

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

二、示例代码

#include <list>

class Subject;

class Observer
{
public:
    virtual ~Observer();
    virtual void Update(Subject* theChangedSubject) = 0;
protected:
    Observer();
};

class Subject
{
public:
    virtual ~Subject(){}
    virtual void Attach(Observer* o)
    {
        _observers->push_back(o);
    }
    virtual void Detach(Observer* o)
    {
        _observers->remove(o);
    }
    virtual void Notity()
    {
        std::list<Observer*>::iterator it = _observers->begin();
        while (it != _observers->end())
        {
            (*it)->Update(this);
            ++it;
        }
    }
protected:
    Subject();
private:
    std::list<Observer*> *_observers;
};

上述代码是一个简单的观察者设计模式代码,逻辑清晰,但这种不能够通用,只能对特定的观察者才有效,即必须是Observer抽象类的派生类才行,并且这个观察者还不能带参数,而且接口参数不支持变化,那么观察者将不能应付接口的变化。那么应该如何解决这个问题呢?可以使用C++11一些特性来改变。

class NonCopyable
{
protected:
    NonCopyable() = default;
    ~NonCopyable() = default;
    NonCopyable(const NonCopyable&) = delete; //禁用拷贝构造
    NonCopyable& operator = (const NonCopyable&) = delete; //禁用赋值构造
};

#include <iostream>
#include <string>
#include <functional>
#include <map>

using namespace std;

扫描二维码关注公众号,回复: 16277149 查看本文章

template<typename Func>
class Events : NonCopyable
{
public:
    Events(){}
    ~Events(){}
    //注册观察者,支持右值
    int Connect(Func&& f)
    {
        return Assgin(f);
    }
    //注册观察者
    int Connect(Func& f)
    {
        return Assgin(f);
    }
    //移除观察者
    void Disconnect(int key)
    {
        m_connections.erase(key);
    }
private:
    //保存观察者并分配观察者编号
    template<typename F>
    int Assgin(F&& f)
    {
        int k = m_observerId++;
        m_connections.emplace(k, std::forward<F> (f));
    }
    int m_observerId = 0;
    std::map<int, Func> m_connections;
};

C++11实现的观察者,内部为了一个泛型函数列表,观察者只需要将观察者函数进行注册进来即可,消除了继承导致的强耦合。通知接口使用了可变参数模板,支持任意参数,这就消除了接口变化的影响。

猜你喜欢

转载自blog.csdn.net/leiyang2014/article/details/132109204