www.weide1946.comPHP常用设计方式之委托设计形式,

2019-07-14 06:09 来源:未知

模式定义

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

动态的给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活【GOF95】
装饰模式是以对客户透明的方式动态地给一个对象附加上更多的职责。这也就是说,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。
一、装饰模式结构图

委托是对一个类的功能进行扩展和复用的方法。它的做法是:写一个附加的类提供附加的功能,并使用原来的类的实例提供原有的功能。

<?php
class 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
?>

 www.weide1946.com 1

假设我们有一个 TeamLead 类,将其既定任务委托给一个关联辅助对象 JuniorDeveloper 来完成:本来 TeamLead 处理 writeCode 方法,Usage 调用 TeamLead 的该方法,但现在 TeamLead 将 writeCode 的实现委托给 JuniorDeveloper 的 writeBadCode 来实现,但 Usage 并没有感知在执行 writeBadCode 方法。

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

二、装饰模式中主要角色
抽象构件(Component)角色:定义一个对象接口,以规范准备接收附加职责的对象,从而可以给这些对象动态地添加职责。
具体构件(Concrete Component)角色:定义一个将要接收附加职责的类。
装饰(Decorator)角色:持有一个指向Component对象的指针,并定义一个与Component接口一致的接口。
具体装饰(Concrete Decorator)角色:负责给构件对象增加附加的职责。
三、装饰模式的优缺点 装饰模式的优点: 1、比静态继承更灵活;
2、避免在层次结构高层的类有太多的特征
装饰模式的缺点: 1、使用装饰模式会产生比使用继承关系更多的对象。并且这些对象看上去都很想像,从而使得查错变得困难。
四、装饰模式适用场景**
1、在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
2、处理那些可以撤消的职责,即需要动态的给一个对象添加功能并且这些功能是可以动态的撤消的。
3、当不能彩生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
五、装饰模式PHP示例
**

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

<?php
class 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();

?>
<?php
/**
 * 抽象构件角色
 */
interface Component {
 /**
  * 示例方法
  */
 public function operation();
}

/**
 * 装饰角色
 */
abstract class Decorator implements Component{

 protected $_component;

 public function __construct(Component $component) {
  $this->_component = $component;
 }

 public function operation() {
  $this->_component->operation();
 }
}

/**
 * 具体装饰类A
 */
class ConcreteDecoratorA extends Decorator {
 public function __construct(Component $component) {
  parent::__construct($component);

 }

 public function operation() {
  parent::operation(); // 调用装饰类的操作
  $this->addedOperationA(); // 新增加的操作
 }

 /**
  * 新增加的操作A,即装饰上的功能
  */
 public function addedOperationA() {
  echo 'Add Operation A <br />';
 }
}

/**
 * 具体装饰类B
 */
class ConcreteDecoratorB extends Decorator {
 public function __construct(Component $component) {
  parent::__construct($component);

 }

 public function operation() {
  parent::operation();
  $this->addedOperationB();
 }

 /**
  * 新增加的操作B,即装饰上的功能
  */
 public function addedOperationB() {
  echo 'Add Operation B <br />';
 }
}

/**
 * 具体构件
 */
class ConcreteComponent implements Component{

 public function operation() {
  echo 'Concrete Component operation <br />';
 }

}

/**
 * 客户端
 */
class Client {

  /**
  * Main program.
  */
 public static function main() {
  $component = new ConcreteComponent();
  $decoratorA = new ConcreteDecoratorA($component);
  $decoratorB = new ConcreteDecoratorB($decoratorA);

  $decoratorA->operation();
  $decoratorB->operation();
 }

}

Client::main();
?>

一,未改进前

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

以上就是使用php实现装饰模式的代码,还有一些关于装饰模式的概念区分,希望对大家的学习有所帮助。

<?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(); 
}

一、未改进前

您可能感兴趣的文章:

  • PHP设计模式之装饰器模式实例详解
  • PHP设计模式之装饰器模式定义与用法详解
  • PHP、Python和Javascript的装饰器模式对比
  • PHP简单装饰器模式实现与用法示例
  • PHP耦合设计模式实例分析
  • PHP设计模式之观察者模式(Observer)详细介绍和代码实例
  • php设计模式 Template (模板模式)
  • php设计模式 Proxy (代理模式)
  • php单态设计模式(单例模式)实例
  • PHP设计模式之装饰器模式定义与用法简单示例

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

<?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(); 
}
<?php
namespace Tools;
/*
委托模式
去除核心对象中的判决和复杂功能性
*/

//委托接口
interface Delegate{
public function playList($list,$song);
}
//mp3处理类
class mp3 implements Delegate{
public function playList($list,$song){
return $list[$song].'.mp3';
}
}
//mp4处理类
class mp4 implements Delegate{
public function playList($list, $song)
{
return $list[$song].'.mp4';
}
}
class cdDelegate{
protected $cdInfo = array();

public function addSong($song){
$this->cdInfo[$song] = $song;
}

public function play($type,$song){
$name = 'Tools\'.$type;
$obj = new $name;
return $obj->playList($this->cdInfo,$song);
}
}
$newCd = new cdDelegate();
$newCd->addSong("1");
$newCd->addSong("2");
$newCd->addSong("3");
echo $newCd->play('mp3','1');//只要传递参数就能知道需要选择何种播放模式

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

以上内容给大家介绍了PHP委托设计模式实例详解,希望对大家有所帮助。

<?php

namespace Tools;

/*
委托模式
去除核心对象中的判决和复杂功能性
*/

//委托接口
interface Delegate{
 public function playList($list,$song);
}

//mp3处理类
class mp3 implements Delegate{
 public function playList($list,$song){
  return $list[$song].'.mp3';
 }
}

//mp4处理类
class mp4 implements Delegate{
 public function playList($list, $song)
 {
  return $list[$song].'.mp4';
 }
}

class cdDelegate{
 protected $cdInfo = array();

 public function addSong($song){
  $this->cdInfo[$song] = $song;
 }

 public function play($type,$song){
  $name = 'Tools\'.$type;
  $obj = new $name;
  return $obj->playList($this->cdInfo,$song);
 }
}

$newCd = new cdDelegate();
$newCd->addSong("1");
$newCd->addSong("2");
$newCd->addSong("3");
echo $newCd->play('mp3','1');//只要传递参数就能知道需要选择何种播放模式

您可能感兴趣的文章:

  • 学习php设计模式 php实现装饰器模式(decorator)
  • PHP简单装饰器模式实现与用法示例
  • PHP、Python和Javascript的装饰器模式对比
  • PHP设计模式之注册树模式分析
  • PHP设计模式之工厂模式详解
  • php简单实现单态设计模式的方法分析
  • 轻松掌握php设计模式之访问者模式
  • PHP常用的三种设计模式汇总
  • PHP设计模式之迭代器模式
  • PHP设计模式之观察者模式实例
  • php设计模式之委托模式
  • PHP设计模式之装饰器模式实例详解

再为大家分享一个实例:

<?php
/**
 * 委托模式 示例
 *
 * @create_date: 2010-01-04
 */
class PlayList
{
 var $_songs = array();
 var $_object = null;

 function PlayList($type)
 {
  $object = $type."PlayListDelegation";
  $this->_object = new $object();
 }

 function addSong($location,$title)
 {
  $this->_songs[] = array("location"=>$location,"title"=>$title);
 }

 function getPlayList()
 {
  return $this->_object->getPlayList($this->_songs);
 }
}

class mp3PlayListDelegation
{
 function getPlayList($songs)
 {
  $aResult = array();
  foreach($songs as $key=>$item)
  {
   $path = pathinfo($item['location']);
   if(strtolower($item['extension']) == "mp3")
   {
    $aResult[] = $item;
   }
  }
  return $aResult;
 }
}

class rmvbPlayListDelegation
{
 function getPlayList($songs)
 {
  $aResult = array();
  foreach($songs as $key=>$item)
  {
   $path = pathinfo($item['location']);
   if(strtolower($item['extension']) == "rmvb")
   {
    $aResult[] = $item;
   }
  }
  return $aResult;
 }
}

$oMP3PlayList = new PlayList("mp3");
$oMP3PlayList->getPlayList();
$oRMVBPlayList = new PlayList("rmvb");
$oRMVBPlayList->getPlayList();
?>

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

您可能感兴趣的文章:

  • php设计模式 Delegation(委托模式)
  • PHP设计模式之建造者模式定义与用法简单示例
  • PHP设计模式之装饰器模式定义与用法简单示例
  • www.weide1946.com,PHP耦合设计模式实例分析
  • PHP设计模式之观察者模式定义与用法示例
  • PHP设计模式之适配器模式原理与用法分析
  • PHP设计模式之原型设计模式原理与用法分析
  • PHP设计模式之单例模式原理与实现方法分析
  • PHP常用的三种设计模式汇总
  • PHP设计模式之委托模式定义与用法简单示例
版权声明:本文由韦德娱乐1946_韦德娱乐1946网页版|韦德国际1946官网发布于网络编程,转载请注明出处:www.weide1946.comPHP常用设计方式之委托设计形式,