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

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

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

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

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

Tags: PHP中介者模式 Mediator Pattern

分享到: