zoukankan      html  css  js  c++  java
  • 【设计模式】中介者模式

    1、  定义

    1.1    标准定义

      中介者模式的定义为:Define an object that encapsulates how a set of objectsinteract.Mediator promotes loose coupling by keeping objects from referring to each other explicitly,and it lets you vary their interaction independently.(用一个中介对象封装一系列的对象交互, 中介者使各对象不需要显示地相互作用, 而使其耦合松散,而且可以独立地改变它们之间的交互。)

    1.2 通用类图

      ● Mediator 抽象中介者角色
      抽象中介者角色定义统一的接口,用于各同事角色之间的通信。

      ● Concrete Mediator 具体中介者角色
      具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。

      ● Colleague 同事角色
      每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。每个同事类的行为分为两种:一种是同事本身的行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为( Self-Method),与其他的同事类或中介者没有任何的依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法(DepMethod)。

    2、实现

    2.1 类图

      Colleage抽象同事类,而ConcreteColleage是具体同事类,每个具体同事只知道自己的行为,而不了解其他同事类的情况,但它们却都认识中介者对象,Mediator是抽象中介者,定义了同事对象到中介者对象的接口,ConcreteMediator是具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类,并从具体同事接受消息,向具体同事对象发出命令。

      Colleage类,抽象同事类

      Mediator类,抽象中介者类

      说明:
      1. Mediator 模式中,每个Colleague 维护一个 Mediator,当要进行通信时,每个具体的 Colleague 直接向ConcreteMediator 发信息,至于信息发到哪里,则由 ConcreteMediator 来决定。
      2. ConcreteColleagueA 和 ConcreteColleagueB 不必维护对各自的引用,甚至它们也不知道各个的存在。

    2.2 代码

    2.2.1 mediator类

    // Mediator.h
    
    #ifndef _MEDIATOR_H_
    #define _MEDIATOR_H_
    
    #include <string>
    
    using namespace std;
    
    class Mediator;
    
    class Colleage
    {
    public:
        virtual ~Colleage();
        virtual void SetMediator(Mediator*);
        virtual void SendMsg(string) = 0;
        virtual void GetMsg(string) = 0;
    protected:
        Colleage(Mediator*);
        Mediator* _mediator;
    private:
    };
    
    class ConcreteColleageA : public Colleage
    {
    public:
        ~ConcreteColleageA();
        ConcreteColleageA(Mediator*);
        virtual void SendMsg(string msg);
        virtual void GetMsg(string);
    protected:
    private:
    };
    
    class ConcreteColleageB : public Colleage
    {
    public:
        ~ConcreteColleageB();
        ConcreteColleageB(Mediator*);
        virtual void SendMsg(string msg);
        virtual void GetMsg(string);
    protected:
    private:
    };
    
    class Mediator
    {
    public:
        virtual ~Mediator();
        virtual void SendMsg(string,Colleage*) = 0;
    protected:
        Mediator();
    private:
    };
    
    class ConcreteMediator : public Mediator
    {
    public:
        ConcreteMediator();
        ~ConcreteMediator();
        void SetColleageA(Colleage*);
        void SetColleageB(Colleage*);
        virtual void SendMsg(string msg,Colleage*);
    protected:
    private:
        Colleage* m_ColleageA;
        Colleage* m_ColleageB;
    };
    #endif
    // Mediator.cpp
    
    #include "Mediator.h"
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    Colleage::Colleage(Mediator* pMediator)
    {
        this->_mediator = pMediator;
    }
    
    Colleage::~Colleage(){}
    
    void Colleage::SetMediator(Mediator* pMediator)
    {
        this->_mediator = pMediator;
    }
    
    ConcreteColleageA::ConcreteColleageA(Mediator* pMediator) : Colleage(pMediator){}
    
    ConcreteColleageA::~ConcreteColleageA(){}
    
    void ConcreteColleageA::SendMsg(string msg)
    {
        this->_mediator->SendMsg(msg,this);
    }
    
    void ConcreteColleageA::GetMsg(string msg)
    {
        cout << "ConcreteColleageA Receive:"<< msg << endl;
    }
    
    ConcreteColleageB::ConcreteColleageB(Mediator* pMediator) : Colleage(pMediator){}
    
    ConcreteColleageB::~ConcreteColleageB(){}
    
    void ConcreteColleageB::SendMsg(string msg)
    {
        this->_mediator->SendMsg(msg,this);
    }
    
    void ConcreteColleageB::GetMsg(string msg)
    {
        cout << "ConcreteColleageB Receive:" << msg << endl;
    }
    
    Mediator::Mediator(){}
    
    Mediator::~Mediator(){}
    
    ConcreteMediator::ConcreteMediator(){}
    
    ConcreteMediator::~ConcreteMediator(){}
    
    void ConcreteMediator::SetColleageA(Colleage* p)
    {
        this->m_ColleageA = p;
    }
    
    void ConcreteMediator::SetColleageB(Colleage* p)
    {
        this->m_ColleageB = p;
    }
    
    void ConcreteMediator::SendMsg(string msg,Colleage* p)
    {
        if(p == this->m_ColleageA)
        {
            this->m_ColleageB->GetMsg(msg);
        }
        else if(p == this->m_ColleageB)
        {
            this->m_ColleageA->GetMsg(msg);
        }
    }

    2.2.3 调用

    // mian.cpp
    
    #include "Mediator.h"
    
    int main()
    {
        ConcreteMediator* pMediator = new ConcreteMediator();
    
        Colleage* p1 = new ConcreteColleageA(pMediator);
        Colleage* p2 = new ConcreteColleageB(pMediator);
    
        pMediator->SetColleageA(p1);
        pMediator->SetColleageB(p2);
    
        p1->SendMsg("xxx");
        p2->SendMsg("ooo");
        return 0;
    }

    3、优缺点

    3.1 优点

      中介者模式的优点就是减少类间的依赖,把原有的一对多的依赖变成了一对一的依赖,同事类只依赖中介者,减少了依赖,当然同时也降低了类间的耦合。

    3.2 缺点

      中介者模式的缺点就是中介者会膨胀得很大,而且逻辑复杂,原本N个对象直接的相互依赖关系转换为中介者和同事类的依赖关系,同事类越多,中介者的逻辑就越复杂。

    4、应用

      ● N个对象之间产生了相互的依赖关系( N2) 。
      ● 多个对象有依赖关系, 但是依赖的行为尚不确定或者有发生改变的可能, 在这种情况下一般建议采用中介者模式, 降低变更引起的风险扩散。
      ● 产品开发。一个明显的例子就是MVC框架,把中介者模式应用到产品中,可以提升产品的性能和扩展性,但是对于项目开发就未必, 因为项目是以交付投产为目标,而产品则是以稳定、高效、扩展为宗旨。

  • 相关阅读:
    2019 SDN阅读作业
    第02组 Alpha冲刺(2/6)
    2019 SDN上机第3次作业
    第02组 Alpha冲刺(1/6)
    2019 SDN上机第2次作业
    bzoj 3207 可持久化线段树
    bzoj 3524 可持久化线段树
    HDU 4757 可持久化trie树
    bzoj 3197 DP
    poj 2104 可持久化线段树
  • 原文地址:https://www.cnblogs.com/ChinaHook/p/7242407.html
Copyright © 2011-2022 走看看