30.3 事件触发器的开发(观察者模式+中介者模式)
30.3.1 场景介绍
(1)有一产品它有多个触发事件(如创建事件、修改、删除),如创建文本框时触发OnCreate事件,修改时触发onChange事件,双击时触发onDblClick事件。
(2)当产品触发事件时,会创建相应的产品事件对象(ProductEvent),并将这个事件对象传递给观察者,以便通知观察者该事件的发生。
(3)观察者实现上是一个事件的分发者,相当于中介模式中的中介对象,会把这个事件分发者相应的事件处理对象。
30.3.2 类图
(1)事件的观察者:作为观察者模式中的观察者角色,接收观察期望完成的任务,在这个框架中主要用来接收ProductEvent事件。
(2)事件分发者:作为中介者模式中的中介者角色,它担当着非常重要的任务——分发事件,并同时协调各个同事类(也就是事件的处理者)处理事件。
(3)抽象事件处理者:相当于中介者模式中的抽象同事类。为每个事件处理者定义能够处理事件的级别,但定义与中介者交互的接口(exec)
【编程实验】事件触发器
//Classes.h
#pragma once
//**************************************辅助类********************
//产品事件类型
enum ProductEventType
{
NEW_PRODUCT = 1,
DEL_PRODUCT = 2,
EDIT_PRODUCT = 3,
CLONE_PRODUCT = 4
};
//事件处理类型
enum EventHandlerType
{
NEW = 1,
DEL = 2,
EDIT =3,
CLONE = 4
};
typedef void Object;
//事件对象类(主要用来记录触发事件的源对象)
class EventObject
{
Object* source; //记录事件源对象
public:
EventObject(Object* source)
{
this->source = source;
}
Object* EventSource()
{
return source;
}
};
//Product.h
//*******************************************辅助类***********************************
//以下的Product和ProductManager类是组合关系,为了让Product类只能由ProductManager类来创建
//而外部无法直接创建,可以将Product的构造函数私有化,并在Product中声明ProductManager为友
//元类来达到目的。但以下利用一种适合于其他不支持友元类的语言中的方法,这种方种被称为
//单来源调用(Single Call)的方法。
#pragma once
#include <string>
using namespace std;
class Product;
//ProductManager
class ProductManager
{
private:
//是否可以创建一个产品
bool isPermittedCreate;
public:
//建立一个产品
Product* createProduct(string name);
//获得是否可以创建一个产品
bool isCreateProduct();
//修改一个产品
void editProduct(Product& p,string name);
//废弃一个产品
void abandonProduct(Product& p);
//克隆一个产品
Product& clone(Product& p);
};
//产品类
class Product
{
private:
string name; //产品名称
bool canChanged; //是否允许修改属性
ProductManager* manager;
Product(ProductManager& manager, string name);
public:
static Product& getInstance(ProductManager& manager, string name);
string getName();
void setName(string value);
Product& clone();
};
//Product.cpp
#include "Product.h"
#include "Observable.h"
//********************Product Impl*********************
Product::Product(ProductManager& manager, string name)
{
this->canChanged = false;
this->manager = &manager;
//允许建立产品
if(manager.isCreateProduct())
{
canChanged = true;
this->name = name;
}
}
Product& Product::getInstance(ProductManager& manager, string name)
{
Product* ret = NULL;
if(manager.isCreateProduct())
{
ret = new Product(manager, name);
}
return *ret;
}
string Product::getName(){return name;}
void Product::setName(string value)
{
if(canChanged)
name = value;
}
Product& Product::clone()
{
Product* ret = new Product(*manager, name);
return *ret;
}
//********************ProductManager Impl*********************
Product* ProductManager::createProduct(string name)
{
//首先修改权限,允许创建
isPermittedCreate = true;
Product& p = Product::getInstance(*this, name);
//产生一个创建事件
ProductEvent event(&p, ProductEventType::NEW_PRODUCT);
return &p;
}
//获得是否可以创建一个产品
bool ProductManager::isCreateProduct()
{
return isPermittedCreate;
}
//修改一个产品
void ProductManager::editProduct(Product& p,string name)
{
//修改后的名字
p.setName(name);
//产生一个修改事件
ProductEvent event(&p, ProductEventType::EDIT_PRODUCT);
}
//废弃一个产品
void ProductManager::abandonProduct(Product& p)
{
//产生一个删除事件
ProductEvent event(&p, ProductEventType::DEL_PRODUCT);
delete &p;
}
//克隆一个产品
Product& ProductManager::clone(Product& p)
{
//产生一个克隆事件
ProductEvent event(&p, ProductEventType::CLONE_PRODUCT);
return p.clone();
}
//Observable.h
#pragma once
#include <list>
#include "classes.h"
#include "Observer.h"
using namespace std;
class Product;
//被观察者
class Observable
{
private:
list<Observer*> obs;
EventObject eo;
public:
Observable():eo(0){}
void addObserver(Observer* observer);
EventObject& getEventObject();
void notifyObservers(Observable* o);
virtual ~Observable(){}
};
//产品事件
class ProductEvent : Observable
{
private:
Product* source; //事件起源
ProductEventType type;
void init(Product* p, ProductEventType t);
//通知事件处理中心
void notifyEventDispatch();
public:
//传入事件的源头,默认为新建类型
ProductEvent(Product* p);
ProductEvent(Product* p, ProductEventType type);
//获得事件的始作俑者
Product* getSource();
//获得事件类型
ProductEventType getEventType();
};
//Observable.cpp
复制代码
#include "Observable.h"
//被观察者
void Observable::addObserver(Observer* observer)
{
obs.push_back(observer);
//notifyObservers(this);
}
EventObject& Observable::getEventObject(){return eo;}
void Observable::notifyObservers(Observable* o)
{
list<Observer*>::iterator iter = obs.begin();
while(iter != obs.end())
{
(*iter)->update(o, &eo);
++iter;
}
}
//产品事件
void ProductEvent::init(Product* p, ProductEventType t)
{
this->source = p;
this->type = t;
//事件触发
notifyEventDispatch();
}
//通知事件处理中心
void ProductEvent::notifyEventDispatch()
{
addObserver(EventDispatch::getInstance());
Observable::notifyObservers(this);
}
//传入事件的源头,默认为新建类型
ProductEvent::ProductEvent(Product* p):Observable()
{
init(p, ProductEventType::NEW_PRODUCT);
}
ProductEvent::ProductEvent(Product* p, ProductEventType type):Observable()
{
init(p, type);
}
//获得事件的始作俑者
Product* ProductEvent::getSource()
{
return source;
}
//获得事件类型
ProductEventType ProductEvent::getEventType()
{
return type;
}
//Observer.h
#pragma once
#include <vector>
#include "classes.h"
using namespace std;
class Observable;
class EventHandler;
class Observer
{
public:
virtual void update(Observable* o, EventObject* e) = 0;
virtual ~Observer(){}
};
//事件通知对象
class EventDispatch :public Observer
{
private:
//单例模式
static EventDispatch* dispatch;
//事件处理者
vector<EventHandler*> handlers;
//不允许生成新的实例
EventDispatch(){}
public:
//获得单例对象
static EventDispatch* getInstance();
EventDispatch* getEventDispatch();
//事件触发
void update(Observable* o, EventObject* e);
//注册事件处理者
void registerHandler(EventHandler* eventHandler);
};
//Observer.cpp
#include "Observer.h"
#include "Product.h"
#include "Observable.h"
#include "Handler.h"
//事件通知对象
EventDispatch* EventDispatch::getInstance()
{
return dispatch;
}
EventDispatch* EventDispatch::getEventDispatch()
{
return dispatch;
}
//事件触发
void EventDispatch::update(Observable* o, EventObject* e)
{
//事件的源头
//Product& p = (Product&)(*(Product*)(e->EventSource()));
//事件
ProductEvent& event = (ProductEvent&)(*o);
//处理者处理,这里是中介者模式的核心,可以是很复杂的业务逻辑
vector<EventHandler*>::iterator iter = handlers.begin();
while(iter != handlers.end())
{
//处理能力是否匹配
vector<EventHandlerType>& eht= (*iter)->getHandlerType();
vector<EventHandlerType>::iterator it = eht.begin();
while(it != eht.end())
{
if ((int)(*it) == (int)event.getEventType())
(*iter)->exec(&event);
++it;
}
++iter;
}
}
//注册事件处理者
void EventDispatch::registerHandler(EventHandler* eventHandler)
{
handlers.push_back(eventHandler);
}
EventDispatch* EventDispatch::dispatch = new EventDispatch();
//Handler.h
#pragma once
#include <vector>
#include "Classes.h"
#include "Observable.h"
using namespace std;
class EventHandler
{
protected:
//定义每个事件处理者处理的级别
vector<EventHandlerType> handlerType;
public:
//每个事件处理者都要声明自己处理哪一类别的消息
EventHandler(EventHandlerType type);
void addHandlerType(EventHandlerType type);
//得到自己的处理能力
vector<EventHandlerType>& getHandlerType();
//处理事件
virtual void exec(ProductEvent* e) = 0;
};
//删除事件的处理者
class DelEventHandler: public EventHandler
{
public:
DelEventHandler():EventHandler(EventHandlerType::DEL){}
void exec(ProductEvent* event);
};
//创建事件的处理者
class CreateEventHandler: public EventHandler
{
public:
CreateEventHandler();
void exec(ProductEvent* event);
};
//修改事件的处理者
class EditEventHandler: public EventHandler
{
public:
EditEventHandler():EventHandler(EventHandlerType::EDIT){}
void exec(ProductEvent* event);
};
//Handler.cpp
#include <iostream>
#include "Handler.h"
#include "Product.h"
using namespace std;
//每个事件处理者都要声明自己处理哪一类别的消息
EventHandler::EventHandler(EventHandlerType type)
{
handlerType.push_back(type);
}
void EventHandler::addHandlerType(EventHandlerType type)
{
handlerType.push_back(type);
}
//得到自己的处理能力
vector<EventHandlerType>& EventHandler::getHandlerType()
{
return handlerType;
}
//删除事件的处理者
void DelEventHandler::exec(ProductEvent* event)
{
//事件的源头
Product* p = event->getSource();
//事件类型
ProductEventType type = event->getEventType();
cout <<"删除事件的处理:销毁" << p->getName() <<",事件类型:" << type <<endl;
}
CreateEventHandler::CreateEventHandler():EventHandler(EventHandlerType::NEW)
{
handlerType.push_back(EventHandlerType::CLONE);
};
//创建事件的处理者
void CreateEventHandler::exec(ProductEvent* event)
{
//事件的源头
Product* p = event->getSource();
//事件类型
ProductEventType type = event->getEventType();
if(type == ProductEventType::NEW_PRODUCT)
{
cout <<"新建事件的处理:新建" << p->getName() <<",事件类型:" << type <<endl;
}
else
{
cout <<"克隆事件的处理:克隆" << p->getName() <<",事件类型:" << type <<endl;
}
}
//修改事件的处理者
void EditEventHandler::exec(ProductEvent* event)
{
//事件的源头
Product* p = event->getSource();
//事件类型
ProductEventType type = event->getEventType();
cout <<"修改事件的处理:修改" << p->getName() <<",事件类型:" << type <<endl;
}
//main.cpp
//设计模式混编——观察者模式+中介模式
//实例:事件触发器
#include <iostream>
#include "Product.h"
#include "Handler.h"
using namespace std;
int main()
{
//获得事件分发中心
EventDispatch* dispatch = EventDispatch::getInstance();
//接受修改事件的处理
EditEventHandler editHandler;
dispatch->registerHandler(&editHandler);
//接受删除事件的处理
DelEventHandler delHandler;
dispatch->registerHandler(&delHandler);
//接受创建事件的处理
CreateEventHandler createHandler;
dispatch->registerHandler(&createHandler);
//建立一个导弹生产工厂
ProductManager factory;
//制造一个产品
cout << "==========模拟创建产品事件=========="<<endl;
cout << "创建\"战斧式巡航导弹\"" << endl;
Product* p = factory.createProduct("战斧式巡航导弹");
//导弹维修
cout << "==========模拟维修产品事件=========="<<endl;
cout << "升级\"战斧式巡航导弹\"" << endl;
factory.editProduct(*p, "战斧式巡航导弹II");
//导弹维修
cout << "==========模拟克隆产品事件=========="<<endl;
cout << "克隆\"战斧式巡航导弹II\"" << endl;
factory.clone(*p);
//销毁产品
cout << "==========模拟销毁产品事件=========="<<endl;
cout << "销毁\"战斧式巡航导弹II\"" << endl;
factory.abandonProduct(*p);
delete dispatch;
return 0;
};
/*输出结果:
==========模拟创建产品事件==========
创建"战斧式巡航导弹"
新建事件的处理:新建战斧式巡航导弹,事件类型:1
==========模拟维修产品事件==========
升级"战斧式巡航导弹"
修改事件的处理:修改战斧式巡航导弹II,事件类型:3
==========模拟克隆产品事件==========
克隆"战斧式巡航导弹II"
克隆事件的处理:克隆战斧式巡航导弹II,事件类型:4
==========模拟销毁产品事件==========
销毁"战斧式巡航导弹II"
删除事件的处理:销毁战斧式巡航导弹II,事件类型:2
*/
30.3.3 混编小结
(1)工厂方法模式:负责产生产品对象,方便产品的修改和扩展,并且实现了产品和工厂的紧耦合,避免产品被随意创建而无触发事件的情况发生。
(2)桥梁模式:在产品和事件两个对象的关系中使用了桥梁模式,如果两者均可独立变化。
(3)观察者模式
观察者模式解决了事件如何通知处理者的问题,而且观察者模式还有一个优点是可以有多个观察者,也就是我们的架构是可以有多层次、多分类的处理者。
(4)中介者模式
有了事件和处理者,可以利用中介者模式将两者解耦,它可以完美地处理这些复杂的关系。