C++自己的观察者模式

Kol*_*nya 6 c++ pointers function-pointers observers observer-pattern

我设计应该以这种方式工作的观察者模式:观察者调用AddEventListener的方法EventDispatcher,并传递一个字符串,它是的名称event,PointerToItselfPointerToItsMemberMethod

之后event发生在EventDispatcher; 它查看订阅列表,如果有一些,则分配给此事件调用该action方法observer.

我来这里了EventDispatcher.h.小心包含一些伪代码.

这是两个问题:

  1. 如何定义actionin 的类型struct Subscription
  2. 我正在朝着正确的方向前进吗?

PS:不,我不会使用boost任何其他库.

#pragma once

#include <vector>
#include <string>

using namespace std;

struct Subscription
{
        void*                   observer;
        string                  event;
        /*  u_u  */             action;
};

class EventDispatcher
{
    private:
        vector<Subscription>    subscriptions;

    protected:
        void                    DispatchEvent ( string event );

    public:
        void                    AddEventListener ( Observer* observer , string event , /*  u_u  */ action );
        void                    RemoveEventListener ( Observer* observer , string event , /*  u_u  */ action );
};
Run Code Online (Sandbox Code Playgroud)

这个头实现如下 EventDispatcher.cpp

#include "EventDispatcher.h"

void    EventDispatcher::DispatchEvent ( string event )
{
    int key = 0;
    while ( key < this->subscriptions.size() )
    {
        Subscription subscription = this->subscriptions[key];
        if ( subscription.event == event )
        {
            subscription.observer->subscription.action;
        };
    };
};

void    EventDispatcher::AddEventListener ( Observer* observer , string event , /* */ action )
{
    Subscription subscription = { observer , event , action );
    this->subscriptions.push_back ( subscription );
};

void    EventDispatcher::RemoveEventListener ( Observer* observer , string event , /* */ action )
{
    int key = 0;
    while ( key < this->subscriptions.size() )
    {
        Subscription subscription = this->subscriptions[key];
        if ( subscription.observer == observer && subscription.event == event && subscription.action == action )
        {
            this->subscriptions.erase ( this->subscriptions.begin() + key );
        };
    };
};
Run Code Online (Sandbox Code Playgroud)

Mar*_*cia 1

也许您应该创建一个由“用户”派生的类:

class Action {
   public:
      friend class EventDispatcher;

      virtual SomeResultType DoThis() = 0;

   private:
      /* Some common data */
};
Run Code Online (Sandbox Code Playgroud)

只需将一些派生自类 Action 类型的变量传递给 AddEventListener 即可。当相应的事件触发时,只需填写常用数据并调用DoThis()方法即可。

void EventDispatcher::DispatchEvent ( string event )
{
    int key = 0;
    while ( key < this->subscriptions.size() )
    {
        Subscription subscription = this->subscriptions[key];
        if ( subscription.event == event )
        {
            subscription->action();
        };
    };
};
Run Code Online (Sandbox Code Playgroud)

对于添加事件监听器:

void EventDispatcher::AddEventListener ( Observer* observer , string event , Action* action )
{
    Subscription subscription = { observer , event , action );
    this->subscriptions.push_back ( subscription );
};
Run Code Online (Sandbox Code Playgroud)

Action 派生类的示例:

class myAction: public Action {
   public:
      // Implement the DoThis() method
      void SomeResultType DoThis() {
          cout << "Hello World!";
          return SomeValue;
      }
};

// To use the action,
myAction* act = new myAction;
myEventDispatcher.AddEventListener(someObserver, "HelloWorld", act);
Run Code Online (Sandbox Code Playgroud)

这是实现操作(和回调)的最安全的方法之一。