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

php设计模式之委托模式

发布:smiling 来源: PHP粉丝网  添加日期:2021-07-09 15:00:43 浏览: 评论:0 

这篇文章主要为大家详细介绍了php设计模式之委托模式,以一个实例为大家介绍了php委托模式,感兴趣的朋友可以参考一下。

委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。委托模式是一项基本技巧,许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式。

动态委托的介绍:动态委托概念来自于Jakarta 字节码工程库 (Byte-Code Engineering Library, BCEL)。它能够分析存在的类,并且对于接口,抽象类,甚至运行时的具体类来说,它能够生成以字节编码委托类。

被委托的接口/类应该满足如下条件:动态委托最多只能委托一个类,但是能够代理多个接口。这个限制来自于Java的单继承模式。一个Java类最多只有一个父类。既然生成的委托类把被委托类作为它的父类,那么指定多个被委托类是不合理的。如果没有指定被委托类,那么缺省的父类就是Object。

下面是PHP 反射机制实现动态代理的代码:

  1. <?php 
  2. class Fruit 
  3.  
  4. { 
  5.  
  6.   function callFruit() 
  7.  
  8.   { 
  9.     print "Generate an Apple"; 
  10.   } 
  11.  
  12. } 
  13.  
  14. class FruitDelegator 
  15. { 
  16.  private $targets; 
  17.   function __construct() 
  18.   { 
  19.     $this->target[] = new Fruit(); 
  20.   } 
  21.     
  22.   function __call($name, $args) 
  23.  
  24.   { 
  25.     foreach ($this->target as $obj) 
  26.     { 
  27.       $r = new ReflectionClass($obj); 
  28.       if ($method = $r->getMethod($name)) 
  29.  
  30.       { 
  31.  
  32.         if ($method->isPublic() && !$method->isAbstract()) 
  33.         { 
  34.  
  35.           return $method->invoke($obj, $args); 
  36.         } 
  37.  
  38.       } 
  39.  
  40.     } 
  41.   } 
  42.  
  43. } 
  44.  
  45. $obj = new FruitDelegator(); 
  46.  
  47. $obj->callFruit(); 
  48.  
  49. // 运行结果 
  50.  
  51. // Generate an Apple 
  52. ?> 

可见,通过代理类FruitDelegator来代替Fruit类来实现他的方法。

同样的,如下的代码也是能够运行的:

  1. <?php 
  2. class Color 
  3.  
  4. { 
  5.   function callColor() 
  6.   { 
  7.     print "Generate Red"; 
  8.   } 
  9. } 
  10.    
  11.  
  12. class ColorDelegator 
  13.  
  14. { 
  15.  
  16.   private $targets; 
  17.  
  18.      
  19.  
  20.   function addObject($obj) 
  21.  
  22.   { 
  23.  
  24.     $this->target[] = $obj; 
  25.  
  26.   } 
  27.  
  28.      
  29.  
  30.   function __call($name, $args) 
  31.  
  32.   { 
  33.  
  34.     foreach ($this->target as $obj) 
  35.  
  36.     { 
  37.  
  38.       $r = new ReflectionClass($obj); 
  39.  
  40.       if ($method = $r->getMethod($name)) 
  41.  
  42.       { 
  43.  
  44.         if ($method->isPublic() && !$method->isAbstract()) 
  45.  
  46.         { 
  47.           return $method->invoke($obj, $args); 
  48.         } 
  49.       } 
  50.     } 
  51.   } 
  52. } 
  53.  
  54. $obj = new ColorDelegator(); 
  55. $obj->addObject(new Color()); 
  56. $obj->callColor(); 
  57.  
  58. ?> 

设计了一个cd类,类中有mp3播放模式,和mp4播放模式

改进前,使用cd类的播放模式,需要在实例化的类中去判断选择什么方式的播放模式

改进后,播放模式当做一个参数传入playList函数中,就自动能找到对应需要播放的方法。

一、未改进前

  1. <?php  
  2. //使用委托模式之前,调用cd类,选择cd播放模式是复杂的选择过程  
  3. class cd {  
  4.  protected $cdInfo = array();  
  5.     
  6.  public function addSong($song) {  
  7.   $this->cdInfo[$song] = $song;  
  8.  }  
  9.     
  10.  public function playMp3($song) {  
  11.   return $this->cdInfo[$song] . '.mp3';  
  12.  }  
  13.     
  14.  public function playMp4($song) {  
  15.   return $this->cdInfo[$song] . '.mp4';  
  16.  }  
  17. }  
  18. $oldCd = new cd;  
  19. $oldCd->addSong("1");  
  20. $oldCd->addSong("2");  
  21. $oldCd->addSong("3");  
  22. $type = 'mp3';  
  23. if ($type == 'mp3') {  
  24.  $oldCd->playMp3();  
  25. } else {  
  26.  $oldCd->playMp4();  
  27. } 

二、通过委托模式,改进后的cd类

  1. <?php 
  2.    
  3. namespace Tools; 
  4.    
  5. /* 
  6. 委托模式 
  7. 去除核心对象中的判决和复杂功能性 
  8. */ 
  9.    
  10. //委托接口 
  11. interface Delegate{ 
  12.  public function playList($list,$song); 
  13. } 
  14.    
  15. //mp3处理类 
  16. class mp3 implements Delegate{ 
  17.  public function playList($list,$song){ 
  18.   return $list[$song].'.mp3'; 
  19.  } 
  20. } 
  21.    
  22. //mp4处理类 
  23. class mp4 implements Delegate{ 
  24.  public function playList($list, $song) 
  25.  { 
  26.   return $list[$song].'.mp4'; 
  27.  } 
  28. } 
  29.    
  30. class cdDelegate{ 
  31.  protected $cdInfo = array(); 
  32.    
  33.  public function addSong($song){ 
  34.   $this->cdInfo[$song] = $song; 
  35.  } 
  36.    
  37.  public function play($type,$song){ 
  38.   $name = '\Tools\\'.$type; 
  39.   $obj = new $name; 
  40.   return $obj->playList($this->cdInfo,$song); 
  41.  } 
  42. } 
  43.    
  44. $newCd = new cdDelegate(); 
  45. $newCd->addSong("1"); 
  46. $newCd->addSong("2"); 
  47. $newCd->addSong("3"); 
  48. echo $newCd->play('mp3','1');//只要传递参数就能知道需要选择何种播放模式 

再为大家分享一个实例:

  1. <?php 
  2. /** 
  3.  * 委托模式 示例 
  4.  * 
  5.  * @create_date: 2010-01-04 
  6.  */ 
  7. class PlayList 
  8. { 
  9.  var $_songs = array(); 
  10.  var $_object = null; 
  11.    
  12.  function PlayList($type) 
  13.  { 
  14.   $object = $type."PlayListDelegation"; 
  15.   $this->_object = new $object(); 
  16.  } 
  17.    
  18.  function addSong($location,$title) 
  19.  { 
  20.   $this->_songs[] = array("location"=>$location,"title"=>$title); 
  21.  } 
  22.    
  23.  function getPlayList() 
  24.  { 
  25.   return $this->_object->getPlayList($this->_songs); 
  26.  } 
  27. } 
  28.    
  29. class mp3PlayListDelegation 
  30. { 
  31.  function getPlayList($songs) 
  32.  { 
  33.   $aResult = array(); 
  34.   foreach($songs as $key=>$item) 
  35.   { 
  36.    $path = pathinfo($item['location']); 
  37.    if(strtolower($item['extension']) == "mp3") 
  38.    { 
  39.     $aResult[] = $item; 
  40.    } 
  41.   } 
  42.   return $aResult; 
  43.  } 
  44. } 
  45.    
  46. class rmvbPlayListDelegation 
  47. { 
  48.  function getPlayList($songs) 
  49.  { 
  50.   $aResult = array(); 
  51.   foreach($songs as $key=>$item) 
  52.   { 
  53.    $path = pathinfo($item['location']); 
  54.    if(strtolower($item['extension']) == "rmvb") 
  55.    { 
  56.     $aResult[] = $item; 
  57.    } 
  58.   } 
  59.   return $aResult; 
  60.  } 
  61. } 
  62.    
  63. $oMP3PlayList = new PlayList("mp3"); 
  64. $oMP3PlayList->getPlayList(); 
  65. $oRMVBPlayList = new PlayList("rmvb"); 
  66. $oRMVBPlayList->getPlayList(); 
  67. ?> 

以上就是本文的全部内容,希望对大家的学习有所帮助。

Tags: php设计模式 php委托模式

分享到: