#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
///加深点印象
///定义了事件类型
///业务类可以根据事件类型来判断那条消息需要处理, 不需要的消息就过滤掉
///业务类只有一个收到消息的入口就是OnEvent函数,如果使用单例模式的话,以后开出接口的机会一定会越来越多
typedef enum Event
{
event1 = 1, ///事件1
event2, ///事件2
event3, ///事件3
}Event;
///定义了一个基类IObserver,有一个虚函数OnEvent
class IObserver
{
public:
virtual void OnEvent(Event event, std::string str/*, const Json::Value& value*/){}
};
///业务类A,继承了IObserver,实现了虚函数OnEvent函数
class A : public IObserver
{
public:
void OnEvent(Event event, std::string str/*, const Json::Value& value*/)
{
///业务A类处理了事件event1的消息
if (event == event1)
{
cout << "class A recv Message: "<< str << endl;
}
}
};
///业务类B,继承了IObserver,实现了虚函数OnEvent函数
class B : public IObserver
{
public:
void OnEvent(Event event, std::string str/*, const Json::Value& value*/)
{
///业务B类处理了事件event2的消息
if (event == event2)
{
cout << "class B recv Message: "<< str << endl;
}
}
};
///Manager类有一个存放IObserver类型指针的数组
class Manager
{
public:
///Attach函数的参数是IObserver指针类型,只要继承了IObserver类型的对象指针都能存放到数组中
void Attach(IObserver* observer)
{
vector<IObserver*>::iterator it = find(v.begin(), v.end(), observer);
if (it == v.end())
{
v.push_back(observer);
}
}
///Detach函数是把IObserver类型的对象指针从数组中删除
void Detach(IObserver* observer)
{
vector<IObserver*>::iterator it = find(v.begin(), v.end(), observer);
if (it != v.end())
{
v.erase(it);
}
}
///这是一个运算符重载函数(重载了小括号运算符)
///使用方法:用Mananger类定义一个对象m, 就可以这样调用m(event1, "111");
///将消息发送给每个继承了IObserver类并且实现了OnEvent接口的业务类
void operator()(Event event, string str)
{
///这里将消息发送给不同的业务类,业务类根据事件Event进行消息处理
for(size_t i = 0; i < v.size(); i++)
{
v[i]->OnEvent(event, str);
}
}
size_t GetSize()
{
return v.size();
}
private:
vector<IObserver*> v;
};
int main()
{
A a;
B b;
Manager m;
///将业务类A, 业务类B的对象指针注册到Mananger类的数组中
m.Attach(&a);
m.Attach(&b);
cout << m.GetSize() << endl;
///这是一个运算符重载函数(重载了小括号运算符)
///使用方法:用Mananger类定义一个对象m, 就可以这样调用m(event1, "111");
///调用的函数是类Manager的operator()函数
m(event1, "hello");
m(event2, "hello");
///将业务类A对象指针从Manager的数组中删除
m.Detach(&a);
cout << m.GetSize() << endl;
return 0;
}