首页 > 开发 > PHP > 正文

php设计模式之委托模式

2024-05-04 22:32:30
字体:
来源:转载
供稿:网友

委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。委托模式是一项基本技巧,许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式。
动态委托的介绍:动态委托概念来自于Jakarta 字节码工程库 (Byte-Code Engineering Library, BCEL)。它能够分析存在的类,并且对于接口,抽象类,甚至运行时的具体类来说,它能够生成以字节编码委托类。
被委托的接口/类应该满足如下条件:动态委托最多只能委托一个类,但是能够代理多个接口。这个限制来自于Java的单继承模式。一个Java类最多只有一个父类。既然生成的委托类把被委托类作为它的父类,那么指定多个被委托类是不合理的。如果没有指定被委托类,那么缺省的父类就是Object。
下面是PHP 反射机制实现动态代理的代码:

<?phpclass Fruit{  function callFruit()  {    print "Generate an Apple";  }}class FruitDelegator{ private $targets;  function __construct()  {    $this->target[] = new Fruit();  }    function __call($name, $args)  {    foreach ($this->target as $obj)    {      $r = new ReflectionClass($obj);      if ($method = $r->getMethod($name))      {        if ($method->isPublic() && !$method->isAbstract())        {          return $method->invoke($obj, $args);        }      }    }  }}$obj = new FruitDelegator();$obj->callFruit();// 运行结果// Generate an Apple?>

可见,通过代理类FruitDelegator来代替Fruit类来实现他的方法。
同样的,如下的代码也是能够运行的:

<?phpclass Color{  function callColor()  {    print "Generate Red";  }} class ColorDelegator{  private $targets;     function addObject($obj)  {    $this->target[] = $obj;  }     function __call($name, $args)  {    foreach ($this->target as $obj)    {      $r = new ReflectionClass($obj);      if ($method = $r->getMethod($name))      {        if ($method->isPublic() && !$method->isAbstract())        {          return $method->invoke($obj, $args);        }      }    }  }}$obj = new ColorDelegator();$obj->addObject(new Color());$obj->callColor();?>

设计了一个cd类,类中有mp3播放模式,和mp4播放模式
改进前,使用cd类的播放模式,需要在实例化的类中去判断选择什么方式的播放模式
改进后,播放模式当做一个参数传入playList函数中,就自动能找到对应需要播放的方法。

一、未改进前

<?php //使用委托模式之前,调用cd类,选择cd播放模式是复杂的选择过程 class cd {  protected $cdInfo = array();    public function addSong($song) {   $this->cdInfo[$song] = $song;  }    public function playMp3($song) {   return $this->cdInfo[$song] . '.mp3';  }    public function playMp4($song) {   return $this->cdInfo[$song] . '.mp4';  } } $oldCd = new cd; $oldCd->addSong("1"); $oldCd->addSong("2"); $oldCd->addSong("3"); $type = 'mp3'; if ($type == 'mp3') {  $oldCd->playMp3(); } else {  $oldCd->playMp4(); }            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表