• 第30章 混编模式(3)


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

    #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

    #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

    #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

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

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

  • 相关阅读:
    Xshell 跳板机快速登录脚本按钮
    (一)angularjs5 环境搭建
    Myeclipse 内存溢出解决方法
    php 代码放到服务器上验证码不好用
    表格里面的input在底部
    Smarty忽略大括号
    php富友表单提交接口对接
    php富友接口对接http请求
    js去掉html标签
    删除的时候提示是否删除
  • 原文地址:https://www.cnblogs.com/5iedu/p/5690072.html
Copyright © 2020-2023  润新知