当前位置:首页 > PHP教程 > php高级应用 > 列表

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

发布:smiling 来源: PHP粉丝网  添加日期:2022-01-26 10:01:57 浏览: 评论:0 

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

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

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

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

系统结构复杂:对象之间存在大量的相互关联和调用,若有一个对象发生变化,则需要跟踪和该对象关联的其他所有对象,并进行适当处理

对象可重用性差:由于一个对象和其他对象具有很强的关联,若没有其他对象的支持,一个对象很难被另一个系统或模块重用,这些对象表现出来更像一个不可分割的整体,职责较为混乱

系统扩展性低:增加一个新的对象需要在原有相关对象上增加引用,增加新的引用关系也需要调整原有对象,系统耦合度很高,对象操作很不灵活,扩展性差

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

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

Mediator: 抽象中介者,在里面定义了各个同事之间相互交互所需要的方法。

ConcreteMediator: 具体中介者,它需要了解并为维护每个同事对象,并负责具体的协调各个同事对象的交互关系。

Colleague:抽象同事类,通常实现成为抽象类,主要负责约束同事对象的类型,并实现一些具体同事类之间的公共功能

ConcreteColleague:具体同事类,实现自己的业务,需要与其他同事对象交互,就通知中介对象,中介对象会负责后续的交互

再来看下图片感受下:

PHP中介者模式 Mediator Pattern

来看一个完整的实例:

我们有一个CD类和一个MP3类,两个类的结构相似。

我们需要在CD类更新的时候,同步更新MP3类。

传统的做法就是在CD类中实例化MP3类,然后去更新,但是这么做的话,代码就会很难维护,如果新增一个同样的MP4类,那么就没法处理了。

中介者模式很好的处理了这种情况,通过中介者类,CD类中只要调用中介者这个类,就能同步更新这些数据。

代码实例如下:

  1. <?php 
  2. class CD { 
  3.  public $band = ''
  4.  public $title = ''
  5.  protected $_mediator
  6.  
  7.  public function __construct(MusicContainerMediator $mediator = NULL) { 
  8.  $this->_mediator = $mediator
  9.  } 
  10.  
  11.  public function save() { 
  12.  //具体实现待定 
  13.  var_dump($this); 
  14.  } 
  15.  
  16.  public function changeBandName($bandname) { 
  17.  if ( ! is_null($this->_mediator)) { 
  18.   $this->_mediator->change($thisarray("band" => $bandname)); 
  19.  } 
  20.  $this->band = $bandname
  21.  $this->save(); 
  22.  } 
  23. //MP3Archive类 
  24. class MP3Archive { 
  25.  protected $_mediator
  26.  
  27.  public function __construct(MusicContainerMediator $mediator = NULL) { 
  28.  $this->_mediator = $mediator
  29.  } 
  30.  
  31.  public function save() { 
  32.  //具体实现待定 
  33.  var_dump($this); 
  34.  } 
  35.  
  36.  public function changeBandName($bandname) { 
  37.  if ( ! is_null($this->_mediator)) { 
  38.   $this->_mediator->change($thisarray("band" => $bandname)); 
  39.  } 
  40.  $this->band = $bandname
  41.  $this->save(); 
  42.  } 
  43.  
  44.  
  45.  //中介者类 
  46. class MusicContainerMediator { 
  47.  protected $_containers = array(); 
  48.  
  49.  public function __construct() { 
  50.  $this->_containers[] = "CD"
  51.  $this->_containers[] = "MP3Archive"
  52.  } 
  53.  
  54.  public function change($originalObject$newValue) { 
  55.  $title = $originalObject->title; 
  56.  $band = $originalObject->band; 
  57.  foreach ($this->_containers as $container) { 
  58.   if ( ! ($originalObject instanceof $container)) { 
  59.   $object = new $container
  60.   $object->title = $title
  61.   $object->band = $band
  62.   foreach ($newValue as $key => $val) { 
  63.    $object->$key = $val
  64.   } 
  65.   $object->save(); 
  66.   } 
  67.  } 
  68.  } 
  69.  
  70. //测试实例 
  71. $titleFromDB = "Waste of a Rib"
  72. $bandFromDB = "Never Again"
  73. $mediator = new MusicContainerMediator(); 
  74. $cd = new CD($mediator); 
  75. $cd->title = $titleFromDB
  76. $cd->band = $bandFromDB
  77. $cd->changeBandName("Maybe Once More"); 

运行结果:

  1. object(MP3Archive)#3 (3) { 
  2.   ["_mediator":protected]=> 
  3.   NULL 
  4.   ["title"]=> 
  5.   string(14) "Waste of a Rib" 
  6.   ["band"]=> 
  7.   string(15) "Maybe Once More" 
  8. object(CD)#2 (3) { 
  9.   ["band"]=> 
  10.   string(15) "Maybe Once More" 
  11.   ["title"]=> 
  12.   string(14) "Waste of a Rib" 
  13.   ["_mediator":protected]=> 
  14.   object(MusicContainerMediator)#1 (1) { 
  15.     ["_containers":protected]=> 
  16.     array(2) { 
  17.       [0]=> 
  18.       string(2) "CD" 
  19.       [1]=> 
  20.       string(10) "MP3Archive" 
  21.     } 
  22.   } 

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

  1. //抽象同事类,家教 
  2. abstract class Tutor{ 
  3.   protected $message;  //个人信息 
  4.   protected $mediator//为家教服务的中介机构 
  5.   function __construct($message,Mediator $mediator){ 
  6.     $this->message = $message
  7.     $this->mediator = $mediator
  8.   } 
  9.   //获取个人信息 
  10.   function getMessage(){ 
  11.     return $this->message; 
  12.   } 
  13.   //找学生 
  14.   abstract function findStudent(); 
  15. //具体同事类,大学生家教 
  16. class UndergraduateTutor extends Tutor{ 
  17.   //家教类型 
  18.   public $type = "UndergraduateTutor"
  19.  
  20.   function __construct($message,Mediator $mediator){ 
  21.      parent::__construct($message,$mediator); 
  22.   } 
  23.   //找学生,让中介机构代为寻找 
  24.   function findStudent(){ 
  25.      $this->mediator->matchStudent($this); 
  26.   } 
  27. //具体同事类,高中生家教 
  28. class SeniorStudentTutor extends Tutor{ 
  29.   //家教类型 
  30.   public $type = "SeniorStudentTutor"
  31.  
  32.   function __construct($message,Mediator $mediator){ 
  33.      parent::__construct($message,$mediator); 
  34.   } 
  35.   //找学生,让中介机构代为寻找 
  36.   function findStudent(){ 
  37.      $this->mediator->matchStudent($this); 
  38.   } 
  39. //具体同事类,初中生家教 
  40. class MiddleStudentTutor extends Tutor{ 
  41.   //家教类型 
  42.   public $type = "MiddleStudentTutor"
  43.  
  44.   function __construct($message,Mediator $mediator){ 
  45.      parent::__construct($message,$mediator); 
  46.   } 
  47.   //找学生,让中介机构代为寻找 
  48.   function findStudent(){ 
  49.      $this->mediator->matchStudent($this); 
  50.   } 
  51.  
  52. //抽象中介类 
  53. abstract class AbstractMediator{ 
  54.   abstract function matchStudent(Tutor $tutor); 
  55. //具体中介类,为家教匹配合适的学生 
  56. class Mediator extends AbstractMediator{ 
  57.   //定义其服务的所有家教,不在范围内的不服务 
  58.   private $serveObject = array("UndergraduateTutor","SeniorStudentTutor","MiddleStudentTutor"); 
  59.   //匹配学生 
  60.   function matchStudent(Tutor $tutor){ 
  61.      for($i=0;$i<count($this->serveObject);$i++){ 
  62.        if($tutor->type == $this->serveObject[$i]){ 
  63.          $message = $tutor->getMessage(); 
  64.          echo "该家教个人信息为".print_r($message)."<br/>将为其匹配合适的学生"
  65.          break
  66.        } 
  67.      } 
  68.      if($i>=count($this->serveObject)){ 
  69.        echo "该家教不在我中介机构服务范围内"
  70.      } 
  71.   } 
  72.  
  73. //测试 
  74. $mediator = new Mediator(); 
  75. $undergraduateTutor = new UndergraduateTutor(array("name"=>"张三","age"=>22),$mediator); 
  76. $undergraduateTutor->findStudent(); 

结果:该家教个人信息为 Array ( [name] => 张三 [age] => 22 ),将为其匹配合适的学生

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

Tags: PHP中介者模式 Mediator Pattern

分享到: