第30章 混编模式(3)

30.3 事件触发器的开发(观察者模式+中介者模式)

30.3.1 场景介绍

(1)有一产品它有多个触发事件(如创建事件、修改、删除),如创建文本框时触发OnCreate事件,修改时触发onChange事件,双击时触发onDblClick事件。

(2)当产品触发事件时,会创建相应的产品事件对象(ProductEvent),并将这个事件对象传递给观察者,以便通知观察者该事件的发生

(3)观察者实现上是一个事件的分发者相当于中介模式中的中介对象,会把这个事件分发者相应的事件处理对象。

30.3.2 类图

 第30章 混编模式(3)

(1)事件的观察者:作为观察者模式中的观察者角色,接收观察期望完成的任务,在这个框架中主要用来接收ProductEvent事件

(2)事件分发者:作为中介者模式中的中介者角色,它担当着非常重要的任务——分发事件,并同时协调各个同事类(也就是事件的处理者)处理事件。

(3)抽象事件处理者:相当于中介者模式中的抽象同事类。为每个事件处理者定义能够处理事件的级别,但定义与中介者交互的接口(exec)

【编程实验】事件触发器

//Classes.h

第30章 混编模式(3)

#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;
    }
};

View Code

//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

第30章 混编模式(3)

#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();
}

View Code

//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

第30章 混编模式(3)

#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;
}

View Code

//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

第30章 混编模式(3)

#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();

View Code

//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

第30章 混编模式(3)

#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;
}

View Code

//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)中介者模式

    有了事件和处理者,可以利用中介者模式将两者解耦,它可以完美地处理这些复杂的关系。

原文链接: https://www.cnblogs.com/5iedu/p/5690072.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    第30章 混编模式(3)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/394035

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月3日 下午3:36
下一篇 2023年4月3日 下午3:36

相关推荐