设计模式(17)——中介者 Mediator

24 篇文章 0 订阅
24 篇文章 3 订阅
目录:

设计模式学习笔记首页
设计模式(1)——抽象工厂 AbstractFactory
设计模式(2)——生成器 Builder
设计模式(3)——工厂方法 Factory Method
设计模式(4)——原型 Prototype
设计模式(5)——单例 Singleton
设计模式(6)——适配器 Adapter
设计模式(7)——桥接 Bridge
设计模式(8)——组合 Composite
设计模式(9)——装饰 Decorator
设计模式(10)——外观 Facade
设计模式(11)——享元 Flyweight
设计模式(12)——代理 Proxy
设计模式(13)——职责链 Chain Of Responsibility
设计模式(14)——命令 Command
设计模式(15)——解释器 Interpreter
设计模式(16)——迭代器 Iterator
设计模式(17)——中介者 Mediator
设计模式(18)——备忘录 Memento
设计模式(19)——观察者 Observer
设计模式(20)——状态 State
设计模式(21)——策略 Strategy
设计模式(22)——模板方法 Template Method
设计模式(23)——访问者 Visitor

十七、Mediator(中介者模式,对象行为型模式)

1. 意图:

  用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散而且可以独立地改变它们之间的交互。

2. 动机:

  面向对象设计鼓励将行为分布到各个对象中。这种分布可能会导致对象间有许多连接。在最坏的情况下,每一个对象都知道其他所有对象。
  虽然将一个系统分割成许多对象通常可以增加可复用性,但是对象间相互连接的激增又会降低其可复用性。大量的相互连接使得一个对象似乎不太可能在没有其他对象的支持下工作——系统表现为一个不可分割的整体。而且,对系统的行为进行任何较大的改动都 十分困难,因为行为被分布在许多对象中。结果是,你可能不得不定义很多子类以定制系统的行为。

3. 适用:

  1. 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
  2. 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
  3. 想定制一个分布在多个类中的行为,而又不想生成太多的子类。

4. 类图:

image

5. Facade 与 Mediator

  Facade 与 Mediator 的不同之处在于它是对一个对象子系统进行抽象,从而提供了一个更为方便的接口。它的协议是单向的,即 Facade 对象对这个子系统类提出请求,但反之则不行。相反,Mediator 提供了各 Colleague 对象不支持或不能支持的协作行为,而且协议是多向的。

6. 思考:

  中介者用来集中对象之间复杂的沟通和控制方式。现实中的交换机就类似中介者模式,如果一台电脑需要加入局域网与其它电脑通信,不需要与其它每台电脑单独建立连接,只需要与交换机连接即可,交换机会帮忙处理新电脑与其它电脑的连接。

7. C++实现:

  1. 编写一个中介类接口 Mediator,中介类 ConcreteMediator,含有一些对象间的交互方法如 DoActionFromAtoB()DoActionFromBtoA()
  2. 编写一个同事类接口 Colleague,同事类 ConcreteColleague,包含交互方法 Action(),方法体调用中介的交互方法 DoActionFromAtoB()DoActionFromBtoA()
  3. 中介类编写一个引入对象的方法 IntroColleague()
  4. Colleague has-a 中介类对象 _mdt,通过同事类的构造函数初始化
Mediator.h
//Mediator.h
#pragma once

class Colleague;

class Mediator {
public:
    virtual ~Mediator();
    virtual void DoActionFromAtoB() = 0;
    virtual void DoActionFromBtoA() = 0;
protected:
    Mediator();
private:
};

class ConcreteMediator : public Mediator {
public:
    ConcreteMediator();
    ConcreteMediator(Colleague* clgA, Colleague* clgB);
    ~ConcreteMediator();
    void SetConcreteColleageA(Colleague* clgA);
    void SetConcreteColleageB(Colleague* clgB);
    Colleague* GetConcreteColleagueA();
    Colleague* GetConcreteColleagueB();
    void IntroColleague(Colleague* clgA, Colleague* clgB);
    void DoActionFromAtoB();
    void DoActionFromBtoA();
protected:
private:
    Colleague* _clgA;
    Colleague* _clgB;
};
Mediator.cpp
//Mediator.cpp
#include "Mediator.h"
#include "Colleague.h"

Mediator::Mediator() {}
Mediator::~Mediator(){}

ConcreteMediator::ConcreteMediator() {}
ConcreteMediator::ConcreteMediator(Colleague* clgA, Colleague* clgB){
    this->_clgA = clgA;
    this->_clgB = clgB;
}
ConcreteMediator::~ConcreteMediator() {}

void ConcreteMediator::SetConcreteColleageA(Colleague * clgA){
    this->_clgA = clgA;
}

void ConcreteMediator::SetConcreteColleageB(Colleague * clgB){
    this->_clgB = clgB;
}

Colleague * ConcreteMediator::GetConcreteColleagueA(){
    return _clgA;
}

Colleague * ConcreteMediator::GetConcreteColleagueB(){
    return _clgB;
}

void ConcreteMediator::IntroColleague(Colleague * clgA, Colleague * clgB){
    this->_clgA = clgA;
    this->_clgB = clgB;
}

void ConcreteMediator::DoActionFromAtoB() {
    _clgB->SetState(_clgA->GetState());
}
void ConcreteMediator::DoActionFromBtoA() {
    _clgA->SetState(_clgB->GetState());
}
Colleague.h
//Colleague.h
#pragma once

#include <string>
using namespace::std;

class Mediator;

class Colleague {
public:
    virtual ~Colleague();
    virtual void Action() = 0;
    virtual void SetState(const string& sdt) = 0;
    virtual string GetState() = 0;
protected:
    Colleague();
    Colleague(Mediator* mdt);
    Mediator* _mdt;
private:
};

class ConcreteColleagueA : public Colleague {
public:
    ConcreteColleagueA();
    ConcreteColleagueA(Mediator* mdt);
    ~ConcreteColleagueA();
    void Action();
    void SetState(const string& sdt);
    string GetState();
protected:
private:
    string _sdt;
};

class ConcreteColleagueB : public Colleague {
public:
    ConcreteColleagueB();
    ConcreteColleagueB(Mediator* mdt);
    ~ConcreteColleagueB();
    void Action();
    void SetState(const string& sdt);
    string GetState();
protected:
private:
    string _sdt;
};
Colleague.cpp
//Colleague.cpp

#include "Colleague.h"
#include "Mediator.h"

#include <iostream>
using namespace ::std;

Colleague::Colleague() {}
Colleague::Colleague(Mediator* mdt) {
    this->_mdt = mdt;
}
Colleague::~Colleague() {}

ConcreteColleagueA::ConcreteColleagueA() {}
ConcreteColleagueA::ConcreteColleagueA(Mediator* mdt) : Colleague(mdt) {}
ConcreteColleagueA::~ConcreteColleagueA() {}

void ConcreteColleagueA::Action(){
    _mdt->DoActionFromAtoB();
    cout << "State of ConcreteColleagueB: " << this->GetState() << endl;
}

void ConcreteColleagueA::SetState(const string& sdt) {
    _sdt = sdt;
}
string ConcreteColleagueA::GetState() {
    return _sdt;
}

ConcreteColleagueB::ConcreteColleagueB(){}

ConcreteColleagueB::ConcreteColleagueB(Mediator * mdt) : Colleague(mdt){}

ConcreteColleagueB::~ConcreteColleagueB(){}

void ConcreteColleagueB::Action(){
    _mdt->DoActionFromBtoA();
    cout << "State of ConcreteColleagueB: " << this->GetState() << endl;
}

void ConcreteColleagueB::SetState(const string & sdt){
    this->_sdt = sdt;
}

string ConcreteColleagueB::GetState(){
    return _sdt;
}
main.cpp
//main.cpp
#include "Mediator.h"
#include "Colleague.h"

#include <iostream>
using namespace::std;

int main(int argc, char* argv[]) {
    ConcreteMediator* m = new ConcreteMediator();
    ConcreteColleagueA* c1 = new ConcreteColleagueA(m);
    ConcreteColleagueB* c2 = new ConcreteColleagueB(m);

    m->IntroColleague(c1, c2);

    c1->SetState("old");
    c2->SetState("old");
    c1->Action();
    c2->Action();
    cout << endl;

    c1->SetState("new");
    c1->Action();
    c2->Action();
    cout << endl;

    c2->SetState("old");
    c2->Action();
    c1->Action();

    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值