事件聚合器(Event Aggregator)允许不同的组件订阅和发布事件,而不需要知道事件的发布者和订阅者是谁,模块可在不直接相互引用的情况下通信,实现模块间的松耦合。事件聚合器常用于C#语言中,以下为C++语言的简单实现。
C++事件聚合器的实现
#pragma once
#include <map>
#include <functional>
#include <vector>
#include <iostream>
class EventBase
{
};
template<typename TEventArg>
class PubSubEvent : public EventBase
{
public:
void Sub(std::function<void(TEventArg*)> action)
{
actions.push_back(action);
}
void Pub(TEventArg* arg)
{
for (auto action : actions)
{
action(arg);
}
}
private:
std::vector<std::function<void(TEventArg*)>> actions;
};
class EventAggregator
{
public:
template<typename T>
static T* GetEvent()
{
auto name = typeid(T).raw_name();
auto itor = events.find(name);
if (itor != events.end())
{
return static_cast<T*>(itor->second);
}
else
{
events[name] = new T();
return static_cast<T*>(events[name]);
}
}
private:
static std::map<const char*, EventBase*> events;
};
std::map<const char*, EventBase*> EventAggregator::events;
Demo
#include <iostream>
#include "EventAggregator.h"
class TestEventArg
{
public:
TestEventArg(std::string name)
{
this->name = name;
}
public:
std::string name;
};
class TestEvent : public PubSubEvent<TestEventArg>
{
};
class TestClass
{
public:
void DoEvent(TestEventArg* arg)
{
std::cout << "TestClass : " << arg->name << std::endl;
}
};
void test(TestEventArg* arg)
{
std::cout << arg->name << std::endl;
}
int main()
{
TestClass testClass;
EventAggregator::GetEvent<TestEvent>()->Sub(test);
EventAggregator::GetEvent<TestEvent>()->Sub(std::bind(&TestClass::DoEvent, &testClass, std::placeholders::_1));
EventAggregator::GetEvent<TestEvent>()->Pub(new TestEventArg("hello"));
EventAggregator::GetEvent<TestEvent>()->Pub(new TestEventArg("world"));
}