Шаблон проектирования C++ Шаблон поведенческого наблюдателя

1. Обзор

        Шаблон наблюдателя определяет отношение зависимости между объектами "один ко многим". Когда состояние объекта изменяется, все объекты, которые зависят от него, получают уведомление и автоматически обновляются.

2. Пример кода

#include <список>

предмет класса;

class Observer
{ public:     virtual ~ Observer();     виртуальная пустота Update(Subject* theChangedSubject) = 0; защищено:     Наблюдатель(); };





class Subject
{ public:     virtual ~Subject(){}     virtual void Attach(Observer* o)     {         _observers->push_back(o);     }     виртуальная пустота Detach(Observer* o)     {         _observers->remove(o);     }     virtual void Notity()     {         std::list<Observer*>::iterator it = _observers->begin();         while (it != _observers->end())         {             (*it)->Update(this);             ++это;         }     } защищено:     Тема(); частный:     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>

использование пространства имен std;

template<typename Func>
class Events : NonCopyable
{ public:     Events(){}     ~Events(){}     //регистрация наблюдателя, поддержка rvalue     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));
    }
    интервал m_observerId = 0;
    std::map<int, Func> m_connections;
};

Наблюдатель, реализованный C++11, для внутреннего списка общих функций, наблюдателю нужно только зарегистрировать функцию наблюдателя, что устраняет сильную связь, вызванную наследованием. Интерфейс уведомлений использует вариативные шаблоны и поддерживает произвольные параметры, что исключает влияние изменений интерфейса.

Guess you like

Origin blog.csdn.net/leiyang2014/article/details/132109204
C++
Recommended