前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP设计模式之中介者模式(Mediator Pattern)入门与应用案例详解

PHP设计模式之中介者模式(Mediator Pattern)入门与应用案例详解

作者头像
砸漏
发布2020-10-20 11:03:30
3740
发布2020-10-20 11:03:30
举报
文章被收录于专栏:恩蓝脚本恩蓝脚本

本文实例讲述了PHP设计模式之中介者模式(Mediator Pattern)。分享给大家供大家参考,具体如下:

咱们先来看下中介者模式(Mediator Pattern)的定义,它就是,用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互,这种模式又称为调停者模式,它是一种对象行为型模式。

我们先来看用户与用户直接聊天的设计方案。

在这个方案设计的过程中,我们可以发挥想象,用户对象之间存在很强的关联性,将导致系统出现如下问题:

  1. 系统结构复杂:对象之间存在大量的相互关联和调用,若有一个对象发生变化,则需要跟踪和该对象关联的其他所有对象,并进行适当处理
  2. 对象可重用性差:由于一个对象和其他对象具有很强的关联,若没有其他对象的支持,一个对象很难被另一个系统或模块重用,这些对象表现出来更像一个不可分割的整体,职责较为混乱
  3. 系统扩展性低:增加一个新的对象需要在原有相关对象上增加引用,增加新的引用关系也需要调整原有对象,系统耦合度很高,对象操作很不灵活,扩展性差

然而,在面向对象的软件设计与开发过程中,根据“单一职责原则”,我们应该尽量将对象细化,使其只负责或呈现单一的职责,但是,对于一个模块来说,可能由很多对象构成,而且这些对象之间可能存在相互的引用,为了减少对象两两之间复杂的引用关系,使之成为一个松耦合的系统,我们需要使用中介者模式,这就是我们使用中介者模式的动机。

来看下中介者模式包含的角色:

  •   Mediator: 抽象中介者,在里面定义了各个同事之间相互交互所需要的方法。
  •   ConcreteMediator: 具体中介者,它需要了解并为维护每个同事对象,并负责具体的协调各个同事对象的交互关系。
  •   Colleague:抽象同事类,通常实现成为抽象类,主要负责约束同事对象的类型,并实现一些具体同事类之间的公共功能
  •   ConcreteColleague:具体同事类,实现自己的业务,需要与其他同事对象交互,就通知中介对象,中介对象会负责后续的交互

再来看下图片感受下:

来看一个完整的实例:

  1. 我们有一个CD类和一个MP3类,两个类的结构相似。
  2. 我们需要在CD类更新的时候,同步更新MP3类。
  3. 传统的做法就是在CD类中实例化MP3类,然后去更新,但是这么做的话,代码就会很难维护,如果新增一个同样的MP4类,那么就没法处理了。
  4. 中介者模式很好的处理了这种情况,通过中介者类,CD类中只要调用中介者这个类,就能同步更新这些数据。

代码实例如下:

代码语言:javascript
复制
<?php
class CD {
 public $band = '';
 public $title = '';
 protected $_mediator;

 public function __construct(MusicContainerMediator $mediator = NULL) {
 $this- _mediator = $mediator;
 }

 public function save() {
 //具体实现待定
 var_dump($this);
 }

 public function changeBandName($bandname) {
 if ( ! is_null($this- _mediator)) {
  $this- _mediator- change($this, array("band" =  $bandname));
 }
 $this- band = $bandname;
 $this- save();
 }
}
//MP3Archive类
class MP3Archive {
 protected $_mediator;

 public function __construct(MusicContainerMediator $mediator = NULL) {
 $this- _mediator = $mediator;
 }

 public function save() {
 //具体实现待定
 var_dump($this);
 }

 public function changeBandName($bandname) {
 if ( ! is_null($this- _mediator)) {
  $this- _mediator- change($this, array("band" =  $bandname));
 }
 $this- band = $bandname;
 $this- save();
 }

}

 //中介者类
class MusicContainerMediator {
 protected $_containers = array();

 public function __construct() {
 $this- _containers[] = "CD";
 $this- _containers[] = "MP3Archive";
 }

 public function change($originalObject, $newValue) {
 $title = $originalObject- title;
 $band = $originalObject- band;
 foreach ($this- _containers as $container) {
  if ( ! ($originalObject instanceof $container)) {
  $object = new $container;
  $object- title = $title;
  $object- band = $band;
  foreach ($newValue as $key =  $val) {
   $object- $key = $val;
  }
  $object- save();
  }
 }
 }
}

//测试实例
$titleFromDB = "Waste of a Rib";
$bandFromDB = "Never Again";
$mediator = new MusicContainerMediator();
$cd = new CD($mediator);
$cd- title = $titleFromDB;
$cd- band = $bandFromDB;
$cd- changeBandName("Maybe Once More");

运行结果:

object(MP3Archive)#3 (3) { [“_mediator”:protected]= NULL [“title”]= string(14) “Waste of a Rib” [“band”]= string(15) “Maybe Once More” } object(CD)#2 (3) { [“band”]= string(15) “Maybe Once More” [“title”]= string(14) “Waste of a Rib” [“_mediator”:protected]= object(MusicContainerMediator)#1 (1) { [“_containers”:protected]= array(2) { [0]= string(2) “CD” [1]= string(10) “MP3Archive” } } }

还有个实例,一起看下吧:

代码语言:javascript
复制
//抽象同事类,家教
abstract class Tutor{
  protected $message;  //个人信息
  protected $mediator; //为家教服务的中介机构
  function __construct($message,Mediator $mediator){
    $this- message = $message;
    $this- mediator = $mediator;
  }
  //获取个人信息
  function getMessage(){
    return $this- message;
  }
  //找学生
  abstract function findStudent();
}
//具体同事类,大学生家教
class UndergraduateTutor extends Tutor{
  //家教类型
  public $type = "UndergraduateTutor";

  function __construct($message,Mediator $mediator){
     parent::__construct($message,$mediator);
  }
  //找学生,让中介机构代为寻找
  function findStudent(){
     $this- mediator- matchStudent($this);
  }
}
//具体同事类,高中生家教
class SeniorStudentTutor extends Tutor{
  //家教类型
  public $type = "SeniorStudentTutor";

  function __construct($message,Mediator $mediator){
     parent::__construct($message,$mediator);
  }
  //找学生,让中介机构代为寻找
  function findStudent(){
     $this- mediator- matchStudent($this);
  }
}
//具体同事类,初中生家教
class MiddleStudentTutor extends Tutor{
  //家教类型
  public $type = "MiddleStudentTutor";

  function __construct($message,Mediator $mediator){
     parent::__construct($message,$mediator);
  }
  //找学生,让中介机构代为寻找
  function findStudent(){
     $this- mediator- matchStudent($this);
  }
}

//抽象中介类
abstract class AbstractMediator{
  abstract function matchStudent(Tutor $tutor);
}
//具体中介类,为家教匹配合适的学生
class Mediator extends AbstractMediator{
  //定义其服务的所有家教,不在范围内的不服务
  private $serveObject = array("UndergraduateTutor","SeniorStudentTutor","MiddleStudentTutor");
  //匹配学生
  function matchStudent(Tutor $tutor){
     for($i=0;$i<count($this- serveObject);$i++){
       if($tutor- type == $this- serveObject[$i]){
         $message = $tutor- getMessage();
         echo "该家教个人信息为".print_r($message)."<br/ 将为其匹配合适的学生";
         break;
       }
     }
     if($i =count($this- serveObject)){
       echo "该家教不在我中介机构服务范围内";
     }
  }
}

//测试
$mediator = new Mediator();
$undergraduateTutor = new UndergraduateTutor(array("name"= "张三","age"= 22),$mediator);
$undergraduateTutor- findStudent();
//结果:该家教个人信息为 Array ( [name] =  张三 [age] =  22 ),将为其匹配合适的学生

好啦,本次记录就到这里了。

更多关于PHP相关内容感兴趣的读者可查看本站专题:《php面向对象程序设计入门教程》、《PHP数组(Array)操作技巧大全》、《PHP基本语法入门教程》、《PHP运算与运算符用法总结》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档