设计模式专题(二十一) ——中介者模式

设计模式专题(二十一)——中介者模式

(原创内容,转载请注明来源,谢谢)

一、概述

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

中介者模式使得多个类之间互相通信,可以通过中介者快速实现。但是,也需要注意的是,如果系统频繁出现多对多通信的情况,首先需要排查类的设计,有可能是设计问题导致的。

1、优点

中介者模式减少各个类之间的耦合,使得可以读了改变和复用各个类。另外,由于把对象之间的协作进行抽象,将中介作为独立的概念封装到对象中,这样可以更宏观的角度关注对象之间的交互。

2、缺点

由于中介者过于集中化,交互的复杂性都由中介者进行承担,这样中介者会非常复杂。

二、类图

三、具体实现

1、业务分析

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

1)抽象中介者,其负责对中介者进行抽象,定义一些应该实现的功能。

2)具体中介者,其负责实现具体中介的功能,其需要了解各类,并根据各个类发送过来的信息,实现信息交互。当只有一个中介者的情况下,具体中介者和抽象中介者类可以合并。

3)抽象实现类,定义实现类必须实现的功能,以便中介者统一调用。

4)具体实现类,定义具体实现的功能。

2、编程实现

1)抽象中介者

abstract class Mediator{
         public functionexecute($msg, Colleague $colleague){}
         public functionsetColleague(array $arrColleague){}
}

2)抽象实现类

abstract class Colleague{
         protected $mediator;
         public function__construct(Mediator $mediator){
                   $this->mediator= $mediator;
         }
         public functionsend($msg);
}

3)具体中介者

class MediatorConcreteA extends Mediator{
         private $arrColleague;
         public functionsetColleague(array $arrColleague){
                   if(is_array($arrColleague)&& !empty($arrColleague)){
                            foreach($arrColleagueas $colleague){
                                     if(
                                               $colleagueinstanceof Colleague &&
                                               !isset($this->arrColleague[get_class($colleague)])
                                     ){
                                               $this->arrColleague[get_class($colleague)]= $colleague;
                                     }
                            }
                   }
                   return$this;
         }
         //colleagues表示发送消息方
         public functionexecute($msg, Colleague $colleague){
                   if(empty($msg)){
                            returnfalse;
                   }
                   if($colleagueinstanceof ColleagueA){
                            return$this->arrColleague['ColleagueB']->send($msg);
                   }elseif($colleague instanceof ColleagueB){
                            return$this->arrColleague['ColleagueA']->send($msg);
                   }else{
                            returnfalse;
                   }
         }
}

4)具体实现类,共两个

class ColleagueA extends Colleague{
         protected $mediator;
         public function__construct(Mediator $mediator){
                   parent::__construct($mediator);
         }                
         public functionsend($msg){
                   echo'ColleagueA sends ' . $msg;
         }
}
class ColleagueB extends Colleague{
         protected $mediator;
         public function__construct(Mediator $mediator){
                   parent::__construct($mediator);
         }                
         public functionsend($msg){
                   echo'ColleagueB sends ' . $msg;
         }       
}

5)客户端

$mediator = new MediatorConcreteA();
$colleagueA = new ColleagueA($mediator);
$colleagueB = new ColleagueB($mediator);
$mediator->setColleague(array($colleagueA, $colleagueB))
                    ->execute('send msg to B', $colleagueA);

四、总结

中介者模式实现类之间的解耦交互,类的通信全部通过中介者来实现,有点类似发布订阅模式,将信息发送给中介者后,由中介者去决定如何将消息转发。

——written by linhxx 2017.08.29

相关阅读:

设计模式专题(二十) ——职责链模式

设计模式专题(十九) ——命令模式

设计模式专题(十八) ——桥接模式

设计模式专题(十七) ——单例模式

设计模式专题(十六)——迭代器模式

设计模式专题(十五) ——组合模式

设计模式专题(十四)——适配器模式

设计模式专题(十三) ——备忘录模式

设计模式专题(十二)——状态模式

设计模式专题(十一)——抽象工厂模式

设计模式专题(十)——观察者模式

设计模式专题(九) ——外观模式

设计模式专题(八) ——模板方法模式

设计模式专题(七)——建造者模式

设计模式专题(六)——原型模式

设计模式专题(五)——工厂方法模式

设计模式专题(四)——代理模式

设计模式专题(三)——装饰模式

设计模式专题(二)——策略模式

设计模式专题(一)——面向对象的设计原则

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-08-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏雪胖纸的玩蛇日常

第一章 介绍与循环

1343
来自专栏逍遥剑客的游戏开发

基于Unity的编辑器开发(二): 进程间通信

先要做的, 是需要编辑器和Unity共享一部部分代码, 至少协议定义和解析我不想写两遍. 虽然有protobuf这样的工具库, 但是如果不是跨语言的话, 我觉得...

34615
来自专栏安恒网络空间安全讲武堂

(粉丝投稿)64位linux下栈溢出漏洞利用【结尾有巨大彩蛋哦!!】

64位linux下栈溢出漏洞利用 linux_64与linux_86的区别有:可以使用的内存地址不能大于0x00007fffffffffff,否则会抛出异常。其...

6858
来自专栏Seebug漏洞平台

Exim Off-by-one(CVE-2018-6789)漏洞复现分析

前段时间meh又挖了一个Exim的RCE漏洞[1],而且这次RCE的漏洞的约束更少了,就算开启了PIE仍然能被利用。虽然去年我研究过Exim,但是时间过去这么久...

652
来自专栏CSDN技术头条

Go语言实践:从新手入门到上线真实的小型服务所遇到的那些坑

Teamwork团队在去年写了近20万行Go代码,建造了一堆速度奇快的小型HTTP服务,本文列出了他们总结的9条经验教训。 为什么选择Go语言?Go语言,又称G...

1897
来自专栏恰同学骚年

设计模式的征途—22.中介者(Mediator)模式

我们都用过QQ,它有两种聊天方式:一是私聊,二是群聊。使用QQ群,一个用户就可以向多个用户发送相同的信息和文件,从而无需一一发送,节省大量时间。通过引入群的机制...

742
来自专栏苍云横渡学习笔记

【慕课-数据结构-C++语言】队列篇

【本文目录】 队列原理 面向对象的队列设计 环形队列的实现 实际应用 ---- 最近在复习数据结构,看的是慕课的 数据结构探险—队列篇,写写笔记自用。代码放到g...

33812
来自专栏EAWorld

揭秘:RESTEasy如何完美支持JAVA 微服务中的多种数据格式

本文获得stackify.com授权翻译发表,转载需要注明来自公众号EAWorld。

944
来自专栏菩提树下的杨过

将淘宝数据包导入自己的商城系统

淘宝网有一个淘宝助理,可以方便的将淘宝店的商品资源导出成csv格式的数据包。很多商城系统为了能快速输入商品,都会要求开发者能最大限度的利用淘宝数据包直接导入产品...

1849
来自专栏我就是马云飞

LiveDate和LifeRegistry的协同操作

前言 这个是Android Architecture Components(简称AAC)的第三篇,之前的两篇 文章分别介绍了Lifecycle和ViewMode...

1848

扫描关注云+社区