可变参数模板应用 – 观察者模式

      GoF中的观察者模式,是设计中经常使用的模式。

#include<list>

class Subject;

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

class Subject
{
public:
    virtual ~Subject();
    virtual void Attach(Observer *);
    virtual void Detach(Observer *);
    virtual void Notify();
protected:
    Subject();
private:
    std::list<Observer*> mObserverList;
};

void Subject::Attach(Observer *o)
{
    mObserverList.emplace_back(o);
}

void Subject::Detach(Observer *o)
{
    mObserverList.remove(o);
}

void Subject::Notify()
{
    for(auto& o : mObserverList)
    {
        o->Update(this);
    }
}

       但是使用时有些限制,比如Subject和Observer需要绑定,而且Observer的Update接口收到限制,update定义好了,就无法改变。不过这些限制,在C++ 11之后都不用担心了。

#include<map>

template<typename Fun>
class Subject
{
public:
    Subject() {}
    ~Subject() {}

    int Connect(Fun&& f)
    {
        return Assign(f);
    }

    int Connect(const Fun& f)
    {
        return Assign(f);
    }

    void Disconnect(int key)
    {
        mConnections.erase(key);
    }

    template<typename... Args>
    void Notify(Args&&... args)
    {
        for(auto& connection : mConnections)
        {
            connection.second(std::forward<Args>(args)...);
        }
    }

private:
    template<typename F>
    int Assign(F&& f)
    {
        int k = mConnectCount++;
        mConnections.emplace(k, std::forward<F>(f));
        return k;
    }

private:
    int mConnectCount = 0;
    std::map<int, Fun> mConnections;
};

 这样就可以回调任意的函数,包括普通函数,lambda函数,成员函数,可以不受限制。