30.3 事件触发器的开发(观察者模式+中介者模式)
30.3.1 场景介绍
(1)有一产品它有多个触发事件(如创建事件、修改、删除),如创建文本框时触发OnCreate事件,修改时触发onChange事件,双击时触发onDblClick事件。
(2)当产品触发事件时,会创建相应的产品事件对象(ProductEvent),并将这个事件对象传递给观察者,以便通知观察者该事件的发生。
(3)观察者实现上是一个事件的分发者,相当于中介模式中的中介对象,会把这个事件分发者相应的事件处理对象。
30.3.2 类图
(1)事件的观察者:作为观察者模式中的观察者角色,接收观察期望完成的任务,在这个框架中主要用来接收ProductEvent事件。
(2)事件分发者:作为中介者模式中的中介者角色,它担当着非常重要的任务——分发事件,并同时协调各个同事类(也就是事件的处理者)处理事件。
(3)抽象事件处理者:相当于中介者模式中的抽象同事类。为每个事件处理者定义能够处理事件的级别,但定义与中介者交互的接口(exec)
【编程实验】事件触发器
//Classes.h
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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)中介者模式
有了事件和处理者,可以利用中介者模式将两者解耦,它可以完美地处理这些复杂的关系。