php設計模式之委託模式_php技巧

來源:互聯網
上載者:User

委託模式是軟體設計模式中的一項基本技巧。在委託模式中,有兩個對象參與處理同一個請求,接受請求的對象將請求委託給另一個對象來處理。委託模式是一項基本技巧,許多其他的模式,如狀態模式、策略模式、訪問者模式本質上是在更特殊的場合採用了委託模式。
動態委託的介紹:動態委託概念來自於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(); }

二、通過委託模式,改進後的cd類

<?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/** * 委託模式 樣本 * * @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();?>

以上就是本文的全部內容,希望對大家的學習有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.