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

中介者模式适合于 系统中不希望对象之间直接交互,即不希望类之间相互包含,成为朋友。

中介者模式中有四种角色:

(1)中介者:定义了用于同事之间通信的方法

(2)具体中介者:如果只有一个中介者,那么可以只有一个具体中介者,不需要抽象中介者。它包含具体同事的引用,实现他们之间的通信。

(3)同事:抽象类,规定一些方法

(4)具体同事:包含具体中介者的引用,一个具体同事需要和其他同事交互时,将自己的请求通知给他包含的具体中介者即可。

在本例子中,同事A分别需要通知B和C一些消息,而B也需要通知A和C一些消息,同样,C也需要通知A和B一些消息。利用中介者模式实现如下:

(1)Colleague.h

 #ifndef _COLLEAGUE_H_
#define _COLLEAGUE_H_
#include <string>
#include <iostream>
#include "Mediator.h"
using namespace std;
class ConcreteMediator; //中介者模式
//抽象同事和具体同事的定义 如果没有中介者 他们需要相互包含
class Colleague{
public:
virtual void giveMess(string mess[]) = ;
virtual void receiverMess(string mess) = ;
virtual void setName(string name) = ;
virtual string getName() = ; }; //具体同事
class ColleagueA : public Colleague{
public:
ColleagueA(ConcreteMediator *mediator);
void setName(string name) override;
string getName() override;
void giveMess(string mess[]) override;
void receiverMess(string name) override; private:
ConcreteMediator *myMediator;
string name; }; class ColleagueB : public Colleague{
public:
ColleagueB(ConcreteMediator *mediator);
void setName(string name) override;
string getName() override;
void giveMess(string mess[]) override;
void receiverMess(string name) override; private:
ConcreteMediator *myMediator;
string name; }; class ColleagueC : public Colleague{
public:
ColleagueC(ConcreteMediator *mediator);
void setName(string name) override;
string getName() override;
void giveMess(string mess[]) override;
void receiverMess(string name) override; private:
ConcreteMediator *myMediator;
string name; }; #endif

(2)Colleague.cpp

 #include "Colleague.h"

 ColleagueA::ColleagueA(ConcreteMediator *mediator)
{
this->myMediator = mediator;
myMediator->registerColleagueA(this);
} void ColleagueA::setName(string name)
{
this->name = name;
} string ColleagueA::getName()
{
return name;
} void ColleagueA::giveMess(string mess[])
{
//由中介者将消息传递给其同事
myMediator->deliverMess(this, mess);
} void ColleagueA::receiverMess(string mess)
{
cout << name << " get message: " << mess << endl;
} ColleagueB::ColleagueB(ConcreteMediator *mediator)
{
this->myMediator = mediator;
myMediator->registerColleagueB(this);
} void ColleagueB::setName(string name)
{
this->name = name;
} string ColleagueB::getName()
{
return name;
} void ColleagueB::giveMess(string mess[])
{
//由中介者将消息传递给其同事
myMediator->deliverMess(this, mess);
} void ColleagueB::receiverMess(string mess)
{
cout << name << " get message: " << mess << endl;
} ColleagueC::ColleagueC(ConcreteMediator *mediator)
{
this->myMediator = mediator;
myMediator->registerColleagueC(this);
} void ColleagueC::setName(string name)
{
this->name = name;
} string ColleagueC::getName()
{
return name;
} void ColleagueC::giveMess(string mess[])
{
//由中介者将消息传递给其同事
myMediator->deliverMess(this, mess);
} void ColleagueC::receiverMess(string mess)
{
cout << name << " get message: " << mess << endl;
}

(3)Mediator.h

 #ifndef _MEDIATOR_H_
#define _MEDIATOR_H_
#include "Colleague.h"
#include <string>
using namespace std; class Colleague;
class ColleagueA;
class ColleagueB;
class ColleagueC; //中介者 由于本例子中只有一个中介者 所以只定义一个具体中介者 class ConcreteMediator{
public:
void registerColleagueA(ColleagueA *ca);
void registerColleagueB(ColleagueB *cb);
void registerColleagueC(ColleagueC *cc); void deliverMess(Colleague *colleague, string mess[]); private:
ColleagueA *ca;
ColleagueB *cb;
ColleagueC *cc;
}; #endif

(4)Mediator.cpp

 #include "Mediator.h"

 void ConcreteMediator::registerColleagueA(ColleagueA *ca)
{
this->ca = ca;
} void ConcreteMediator::registerColleagueB(ColleagueB *cb)
{
this->cb = cb;
} void ConcreteMediator::registerColleagueC(ColleagueC *cc)
{
this->cc = cc;
} void ConcreteMediator::deliverMess(Colleague *colleague, string mess[])//如果这里需要判断mess的长度,需要将其作为参数传递进来
{
if (typeid(*colleague) == typeid(*ca))
{
//通知其他的同事
cb->receiverMess(colleague->getName() + mess[]);
cc->receiverMess(colleague->getName() + mess[]);
}
else if (typeid(*colleague) == typeid(*cb))
{
ca->receiverMess(colleague->getName() + mess[]);
cc->receiverMess(colleague->getName() + mess[]);
}
else if (typeid(*colleague) == typeid(*cc))
{
ca->receiverMess(colleague->getName() + mess[]);
cb->receiverMess(colleague->getName() + mess[]);
}
}

(5)MediatorMain.cpp

 #include "Colleague.h"
#include "Mediator.h" int main()
{
ConcreteMediator *mediator = new ConcreteMediator(); ColleagueA *ca = new ColleagueA(mediator);
ColleagueB *cb = new ColleagueB(mediator);
ColleagueC *cc = new ColleagueC(mediator); ca->setName("国A");
cb->setName("国B");
cc->setName("国C"); string messA[] = { "要求归还100斤土豆", "要求归还20头牛" };
ca->giveMess(messA);
cout << endl;
string messB[] = { "要求归还10只鸡", "要求归还15匹马" };
cb->giveMess(messB);
cout << endl;
string messC[] = { "要求归还300斤小麦", "要求归还50头驴" };
cc->giveMess(messC); return ;
}

需要注意的是,在中介者中传递消息的时候需要判断当前参数中指向的对象是哪种类型,用到了操作符typeid。它的参数类型是对象,若两个对象是同一个类型则返回true。

中介者模式适合于一个对象需要引用很多其他对象,或者是对象之间的相互引用比较多的情况。

优点也有很多,比如:

(1)将分布于多个对象之间的交互行为集中在一起。

(2)使得各个具体同事之间完全解耦。

等。

(七)中介者模式-C++实现的更多相关文章

  1. 23种设计模式--中介者模式-Mediator Pattern

    一.中介者模式的介绍     中介者模式第一下想到的就是中介,房子中介,婚姻中介啊等等,当然笔者也希望来个婚姻中介给我介绍一个哈哈哈,,回归正题中介者模式分成中介者类和用户类,根据接口编程的方式我们再 ...

  2. 设计模式--中介(Mediator)模式

    时隔很长一段时,现在又重温设计模式,上个星期学习<设计模式--代理(Proxy)模式>http://www.cnblogs.com/insus/p/4128814.html. 温故而知新, ...

  3. 设计模式---接口隔离模式之中介者模式(Mediator)

    一:概念 在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互.Mediator对象起到控制器的作用 二:动机 在软件构建的过程中, ...

  4. 行为型模式(五) 中介者模式(Mediator)

    一.动机(Motivate) 为什么要使用中介者模式呢?如果不使用中介者模式的话,各个同事对象将会相互进行引用,如果每个对象都与多个对象进行交互时,将会形成如下图所示的网状结构.从上图可以发现,如果不 ...

  5. MediatorPattern(中介者模式)

    /** * 中介者模式 * @author TMAC-J * 研究了这么多设计模式,觉得无非就是几点: * 1.若两个类有耦合关系,设立一个中间类,处理两个类的关系,把两个类的耦合降低 * 2.面向接 ...

  6. C#设计模式-中介者模式

    在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室.QQ群和短信平台,这些都是中介者模式在现实生活中的应用,下面就具体分享下我对中介者模式的理解. 一. 中介者(Mediator)模式 从 ...

  7. php实现设计模式之 中介者模式

    <?php /* * 中介者模式:用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用从而使其耦合松散,而且可以独立地改变它们之间的交互 */ /* * 以一个同学qq群为例说明, ...

  8. 轻松掌握:JavaScript代理模式、中介者模式

    代理模式.中介者模式 代理模式 在面向对象设计中,有一个单一职责原则,指就一个类(对象.函数)而言,应该仅有一个引起它变化的原因.如果一个对象承担了过多的职责,就意味着它将变得巨大,引起它变化的原因就 ...

  9. java设计模式之中介者模式

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

随机推荐

  1. JavaScript中的普通函数与构造函数比较

    问题 什么是构造函数?构造函数与普通函数区别是什么?用new关键字的时候到底做了什么?构造函数有返回值怎么办?构造函数能当普通函数调用吗? thisthis永远指向当前正在被执行的函数或方法的owne ...

  2. 基于Eclipse搭建STM32开源开发环境

    最近项目不忙,想着没事看看简单的嵌入式,弄弄物联网什么的.于是就从廉价的STM32开刀了.因为一直是做PC软件开发的,那VS的智能感知那叫一个爽啊,相比之下,觉得这个Keil简直就像文本编辑器一样lo ...

  3. SharePoint 2013 PowerShell命令备份还原报错

    错误截图: 文字描述: Restore-SPSite : <nativehr>0x80070003</nativehr><nativestack></nati ...

  4. Mac电脑清理硬盘"其他"

    作为一个MacBook的使用者,无不感受到苹果对于系统和硬件的完美匹配. 苹果电脑不适合玩游戏,所以我只用它开发iOS使用.电脑里除了Xcode和常用办公软件与通讯软件以外,我没有装其他的任何大应用. ...

  5. Android 内容观察者的原理

    拦截短信,比如当发短信的时候,就把短信读取出来,当系统的短信发生变化的时候,大叫一声,把数据发送到公共的消息邮箱里面,我们的应用通过内容观察者观察公共的消息邮箱 获取ContentResolver对象 ...

  6. objective-c系列-NSArray

    OC数组NSArray 对比         c数组              和       oc数组对象(指针) 定义         int array[10];              NS ...

  7. 安卓开发之UIwebview

    web view在安卓开发中是比较常见的UI,像微信的新闻模块就采用了这个,他的作用越来越广,下面我把以前做的贴了出来,如果有更好的办法,希望大神不吝赐教哈,嘿嘿,纯代码来了: java代码 publ ...

  8. iOS开发之多线程技术

    本篇争取一篇讲清讲透,依然将通过四大方面清晰的对iOS开发中多线程的用法进行详尽的讲解: 一.什么是多线程 1)多线程执行原理 2)线程与进程 3)多线程的优缺点 二.我们为什么要用多线程编程技术 三 ...

  9. IntelliJ IDEA 使用Git怎样记住密码和忘记密码的方法

    IntelliJ IDEA 使用Git怎样记住密码的方法 1.当使用Ctrl+T进行更新时,弹出密码框(此时不要输入任何字符),直接点"Cancel" 2.略等二三秒,会弹出新的密 ...

  10. 跨域调用webapi web端跨域调用webapi

    web端跨域调用webapi   在做Web开发中,常常会遇到跨域的问题,到目前为止,已经有非常多的跨域解决方案. 通过自己的研究以及在网上看了一些大神的博客,写了一个Demo 首先新建一个webap ...