PHP设计模式之中介者模式
上回说道,我们在外打工的经常会和一类人有很深的接触,那就是房产中介。大学毕业后马上就能在喜欢的城市买到房子的X二代不在我们的考虑范围内哈。既然需要长期的租房,那么因为工作或者生活的变动,不可避免的一两年或者三五年就要和房产中介打一次交道。有的时候,我们租房并不一定会知道房主的信息,房主也不用知道我们的信息,全部都由中介来进行处理。在这里,中介就成为了我们沟通的桥梁,这种情况其实就像是房主出国了或者在外地有事儿而将房子完全的托管到了中介手中。类似于这种情况,在代码世界中,就是中介者模式的典型应用。
Gof类图及解释
GoF定义:用一个中介对象来封装一系列的对象交互。 中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互
GoF类图
代码实现
abstract class Mediator
{
abstract public function Send(String $message, Colleague $colleague);
}
class ConcreteMediator extends Mediator
{
public $colleague1;
public $colleague2;
public function Send(String $message, Colleague $colleague)
{
if ($colleague == $this->colleague1) {
$this->colleague2->Notify($message);
} else {
$this->colleague1->Notify($message);
}
}
}
抽象出来的中介者和具体的实现,在这里,我们假定有固定的两个同事类,让他们互相对话,所以进入的同事是1的时候,就去调用2的Notify方法,相当于是让2接收到了1发来的消息
abstract class Colleague
{
protected $mediator;
public function __construct(Mediator $mediator)
{
$this->mediator = $mediator;
}
}
class ConcreteColleague1 extends Colleague
{
public function Send(String $message)
{
$this->mediator->Send($message, $this);
}
public function Notify(String $message)
{
echo "同事1得到信息:" . $message, PHP_EOL;
}
}
class ConcreteColleague2 extends Colleague
{
public function Send(String $message)
{
$this->mediator->Send($message, $this);
}
public function Notify(String $message)
{
echo "同事2得到信息:" . $message;
}
}
同事类及具体的实现,这里我们要确认的一点就是,每一个同事类,只认识中介者,并不认识另外的同事类,这就是中介者的特点,双方不用认识。
$m = new ConcreteMediator();
$c1 = new ConcreteColleague1($m);
$c2 = new ConcreteColleague2($m);
$m->colleague1 = $c1;
$m->colleague2 = $c2;
$c1->Send("吃过饭了吗?");
$c2->Send("没有呢,你打算请客?");
客户端的调用就比较很简单啦!
- 是不是感觉这个模式很适合做一些通讯类的产品?没错,聊天社交、sns、直播之类的都很合适,因为这个模式就是能让用户与用户之间解耦,不需要让一个用户去维护所有有关联的用户对象
- 因为不需要用户去维护关系,所以也就顺便解决了关系之间的多对多维护的问题,同时,也不需要去修改用户类来进行关系的变更,保持了用户类的良好封装
- 但是,中介者集中维护可能导致这个类过于复杂和庞大
- 所以,模式不是万能的,一定要弄清楚业务场景进行取舍地使用
- 中介者适用于一组对象以定义良好但是复杂的方式进行通信的场合,以及想定制一个分布在多个类中的行为,而又不想生成太多子类的场合
作为一名企业家,深知项目管理的重要性,而项目经理,在很多场合下就是一名中介者的角色。从组织角度看,一个项目的开始和结束,作为老板的我并不需要关心是由谁来具体编码实现,我要沟通的人只是项目经理。同理,其他辅助部门包括财务、人事、行政等,他们也不关心谁来写代码,而只需要和项目经理交流了解项目的情况以及需要配合的内容。在项目团队中,写代码的人呢?也不需要知道谁来给他发工资或者考勤问题出在哪里,这一切也交给项目经理解决就好了。所以说,项目经理负责制的项目开发,就是中介者模式的典型应用。我们的手机厂之所以发展的如此之快,也多亏了这些项目经理们,晚上请他们吃大餐去咯~~~
完整代码:https://github.com/zhangyue0503/designpatterns-php/blob/master/15.mediator/source/mediator.php
实例
这回我们不发短信了,实现一个聊天室吧。一个简单的在线聊天室,需求就是让进入聊天室的用户都可以在线聊天,让我们来看看使用中介者模式来如何实现这个聊天室吧!
聊天室类图
<?php
abstract class Mediator
{
abstract public function Send($message, $user);
}
class ChatMediator extends Mediator
{
public $users = [];
public function Attach($user)
{
if (!in_array($user, $this->users)) {
$this->users[] = $user;
}
}
public function Detach($user)
{
$position = 0;
foreach ($this->users as $u) {
if ($u == $user) {
unset($this->users[$position]);
}
$position++;
}
}
public function Send($message, $user)
{
foreach ($this->users as $u) {
if ($u == $user) {
continue;
}
$u->Notify($message);
}
}
}
abstract class User
{
public $mediator;
public $name;
public function __construct($mediator, $name)
{
$this->mediator = $mediator;
$this->name = $name;
}
}
class ChatUser extends User
{
public function Send($message)
{
$this->mediator->Send($message . '(' . $this->name . '发送)', $this);
}
public function Notify($message)
{
echo $this->name . '收到消息:' . $message, PHP_EOL;
}
}
$m = new ChatMediator();
$u1 = new ChatUser($m, '用户1');
$u2 = new ChatUser($m, '用户2');
$u3 = new ChatUser($m, '用户3');
$m->Attach($u1);
$m->Attach($u3);
$m->Attach($u2);
$u1->Send('Hello, 大家好呀!'); // 用户2、用户3收到消息
$u2->Send('你好呀!'); // 用户1、用户3收到消息
$m->Detach($u2); // 用户2退出聊天室
$u3->Send('欢迎欢迎!'); // 用户1收到消息
说明
- 有没有发现,中介者就是这个“聊天室”,由它来进行信息的传递转移
- 这里由于不固定用户人数,因此是一个数组维护的,当用户发送消息的时候,除了他自己,其他人都收到了这条消息
- 聊天室可以自由地进出用户,说实话,这个例子真的很像一个已经差不多实现功能了的聊天应用哦
- 果然中介者模式真的很适合通信方面的应用,但是,如果进入的用户非常多,$users列表就会越来越臃肿了哦,这就是上文中所述的中介者模式的问题所在
下期看点
中介者模式是不是很有趣,在某些场景下也确实非常有用。但是就像之前说的,设计模式并不是万能药,利用各种模式的组合才能形成完整的框架。这就是现在流行的各种框架的基础。所以,学以致用,并且合适的用,才是我们学习的最终目标。别急别急,先把模式一个一个弄清楚了再说框架的事,下一个即将到来的是建造者模式,还请继续期待哟。
关注公众号:【硬核项目经理】获取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料
知乎、公众号、抖音、头条搜索【硬核项目经理】
B站ID:482780532
PHP设计模式之中介者模式的更多相关文章
- 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)
原文:乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) 作者:weba ...
- 折腾Java设计模式之中介者模式
博文原址:折腾Java设计模式之中介者模式 中介者模式 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性.这种模式提供了一个中介类,该类通常处理不同类之间的通信,并 ...
- js设计模式——8.中介者模式
js设计模式——8.中介者模式 /*js设计模式——中介者模式*/ class A { constructor() { this.number = 0; } setNumber(num, m) { t ...
- 【GOF23设计模式】中介者模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_中介者模式.同事协作类.内部类实现 package com.test.mediator; /** * 同事类的接口 */ ...
- [设计模式] 17 中介者模式 Mediator Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对中介者模式是这样说的:用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变 ...
- 再起航,我的学习笔记之JavaScript设计模式23(中介者模式)
中介者模式 概念介绍 中介者模式(Mediator):通过中介者对象封装一系列对象之间的交互,使对象之间不再相互引用降低他们之间的耦合,有时中介者对象也可以改变对象之间的交互. 创建一个中介 中介者模 ...
- 设计模式之中介者模式(Mediator )
中介者模式是关于数据交互的设计模式,该模式的核心是一个中介者对象,负责协调一系列对象之间的不同的数据请求,这一系列对象成为同事类.如房产中介(简直不想提它),买房的卖房的,租房的放租的都到房产中介那里 ...
- PHP设计模式系列 - 中介者模式
中介者模式 中介者模式用于开发一个对象,这个对象能够在类似对象相互之间不直接相互的情况下传送或者调解对这些对象的集合的修改.一般处理具有类似属性,需要保持同步的非耦合对象时,最佳的做法就是中介者模式. ...
- 深入理解JavaScript系列(36):设计模式之中介者模式
介绍 中介者模式(Mediator),用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 主要内容来自:http://www ...
- Java 设计模式之中介者模式
本文继续23种设计模式系列之中介者模式. 定义 用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互. 角色 抽象中介者: ...
随机推荐
- Sqli-Labs less46-53
less-46 前置基础知识: select * from users order by 1 desc ;使用降序(倒序)排列 select * from users order by 1 asc ; ...
- 【网络编程】TCPIP-5-UDP
目录 前言 5. UDP 网络编程 5.1 UDP 的工作原理 5.2 UDP 的高效性 5.3 实现 UDP 服务端/客户端 5.3.1 概念 5.3.2 UDP 的数据 I/O 函数 5.3.3 ...
- mybaits进阶01
在以上mybait入门的改进(增加了接口让增删改查 后期跟容易) 注意:主配置文件和映射配置文件内容不变,但是映射文件要和对应接口放于同目录下并且名称必须相同 一.接口创建 public interf ...
- 超详细,自动化测试接入Jenkins+Sonar质量门禁实践
大家好,我叫董鑫,一名在测试开发道路上的新手.第一阶段的学习已然结束,收获颇多,了解了很多在自己平时测试工作无法接触到的新知识,比如这次在这里分享的Sonarqube进行静态代码扫描并集成Jenkin ...
- dubbo-admin管理控制台安装
拉项目切换分支到master git clone https://github.com/apache/dubbo-admin.git /var/tmp/dubbo-admin 打开项目修改配置 dub ...
- springmvc学习日志三
一.文件的上传 1.首先在lib中添加相应的jar包 2.建立jsp页面,表单必须是post提交,编码必须是multipart/form-data,文件上传文本框必须起名 <body> & ...
- 【java虚拟机】垃圾回收机制详解
作者:平凡希 原文地址:https://www.cnblogs.com/xiaoxi/p/6486852.html 一.为什么需要垃圾回收 如果不进行垃圾回收,内存迟早都会被消耗空,因为我们在不断的分 ...
- 学校acm比赛题
这道题 用位运算必然简单 但是苦逼的是自己不熟练 那就 用本办法 输入一个十进制数 转换成二进制翻转 去掉高位的零 然后再转化为十进制 输出! 1 #include<stdio.h> ...
- Ztree 树插件 树节点名称太长的解决方案
样式允许的情况下 给背景div加滚动条.. 或者使用省略号方法:使用addDiyDom http://blog.csdn.net/zhengbo0/article/details/17759543 ...
- Git撤销&回滚操作(git reset 和 get revert)
转自:https://blog.csdn.net/asoar/article/details/84111841 git的工作流 工作区:即自己当前分支所修改的代码,git add xx 之前的!不包括 ...