国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > PHP > 正文

PHP訪問者模式與組合模式詳解

2020-03-22 18:33:36
字體:
來源:轉載
供稿:網友
下面小編就為大家帶來一篇淺談PHPhtml' target='_blank'>面向對象之訪問者模式+組合模式。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

因為原文中延續了組合模式的代碼示例來講訪問者模式 所以這里就合并一起來復習了。但主要還是講訪問者模式。顧名思義這個模式會有一個訪問者類(就像近期的熱播劇“人民的名義”中的檢查官,跑到到貪官家里調查取證,查實后就定罪),被訪問者類調用訪問者類的時候會將自身傳遞給它使用。

直接看代碼:


//被訪問者基類abstract class Unit {  abstract function bombardStrength();  //獲取單位的攻擊力    //這個方法將調用訪問者類,并將自身傳遞給它  function accept(ArmyVisitor $visitor){    $method = "visit" . get_class($this);    $visitor->$method($this);      //調用訪問者類的方法,這里使用了 "visit" . get_class($this) 組成了方法的名稱  }    //按原文的說法是設置一個深度,雖然之后會有調用但這個方法對于理解這個模式不重要可以不用管他(原文示例代碼中經常有些跟理解模式原理沒太多關系的代碼)  protected function setDepth($depth){    $this->depth = $depth;  }  function getDepth(){    return $this->depth;  }} //弓箭手class Archer extends Unit{  function bombardStrength(){    return 4;  }}//激光炮class LaserCannonUnit extends Unit{  function bombardStrength(){    return 44;  }}//騎兵class Cavalry extends Unit{  function bombardStrength(){    return 2;          //騎兵的攻擊力居然比弓箭手低?  }} //用于組合繼承了unit類的實例,并讓Army和TroopCarrier類繼承removeUnit和addUnit方法,不放基類是因為上述的三個類已經是最小單位了不是一個軍事集團removeUnit和addUnit方法對他們沒用。abstract class CompositeUnit extends Unit{  private $units = array();    //存放任何繼承了unit 類的實例  function getComposite(){   //這個方法主要用于判斷當前實例是否是一個 CompositeUnit 類    return $this;  }  protected function units(){    return $this->units;  }  function removeUnit(Unit $unit){    //刪除一個軍事單位    $this->units = array_udiff(      $this->units,array($unit),      function($a,$b){return ($a === $b)?0:1;}    );    }  function addUnit(Unit $unit){        //添加一個軍事單位    if(in_array($unit,$this->units,true)){      return;    }    $unit->setDepth($this->depth + 1);      $this->units[] = $unit;  }  function bombardStrength(){    $ret = 0;    foreach($this->units as $unit){      $ret +=$unit->bombardStrength();    }    return $ret;  }  function accept(Armyvisitor $visitor){    //調用訪問者    parent::accept($visitor);        //調用基類的accept方法,在第一個客戶端代碼條用里將會保存軍事集團整體的一個信息    foreach($this->units as $thisunit){   //調用軍事單位accept方法,在第一個客戶端代碼條用里將會保存其中每一個軍事單位的信息      $thisunit->accept($visitor);    }  }} //軍隊class Army extends CompositeUnit {}//艦隊class TroopCarrier extends CompositeUnit {} //訪問者類abstract class ArmyVisitor{  abstract function visit(Unit $node);  //訪問者要執行的業務邏輯  function visitArcher(Archer $node){  //其實我覺得對于理解來說這個抽象類有一個抽象方法visit()就夠了,原文還多出下面這些方法來繞個圈調用visit    //......     $this->visit($node);  }  function visitCavalry(Cavalry $node){    //.......    $this->visit($node);  }  function visitLaserCannonUnit(LaserCannonUnit $node){    //......    $this->visit($node);  }  function visitTroopCarrierUnit(Cavalry $node){    //......    $this->visit($node);  }  function visitArmy(Cavalry $node){    //......    $this->visit($node);  }}//這個訪問者類主要用于獲取并保存被訪問者對象的信息class TextDumpArmyVisitor extends ArmyVisitor {  private $text = "";  function visit(Unit $node){    $ret = "";    $pad = 4 * $node->getDpth();    $ret .= sprintf("%{$pad}s","");    $ret .=get_class($node).": ";    $ret .= "bombard: " . $node->bombardStrength() . "/n";    $this->text .=$ret;  }  function getText(){    return $this->text;  }}//用于向每個對象征稅的訪問者類,客戶端代碼2中將會調用class TaxCollectionVisitor extends ArmyVisitor{  private $due=0;  private $report ="";  function visit(Unit $node){    $this->levy($node,1);  }  function visitArcher(Archer $node){    //復寫了父類的方法,對于不同的單位征收不同的稅    $this->levy($node,2);  }  function visitCavalry(Cavalry $node){    $this->levy($node,3);  }  function visitTroopCarrierUnit(TroopCarrierUnit $node){    $this->levy($node,5);  }  private function levy(Unit $unit,$amount){        //主要的業務邏輯    $this->report .= "Tax levied for" . get_class($unit);    $this->report .= ": $amount/n";    $this->due +=$amount;  }  function getReport(){    return $this->report;  }  function getTax(){    return $this->due;  }}//客戶端代碼1(獲取并輸出每個對象的一些信息)class UnitScript {  static function joinExisting(Unit $newUnit,Unit $occupyingUnit){    $comp;    if(!is_null($com = $occupyingUnit->getComposite())){      $comp->addUnit($newUnit);    } else {      $comp = new Army();      $comp->addUnit($occupyingUnit);      $com->addUnit($newUnit);    }    return $comp;  }} $main_army = new Army();UnitScript::joinExisting(new Archer(),$main_army);UnitScript::joinExisting(new LaserCannonUnit(),$main_army);UnitScript::joinExisting(new Cavalry(),$main_army);$textdump = new TextDumpArmyVisitor();$main_army->accept($textdump);print $textdump->getText(); //客戶端代碼2(對每個對象征稅,最后輸出總共征收了多少)$main_army = new Army();UnitScript::joinExisting(new Archer(),$main_army);UnitScript::joinExisting(new LaserCannonUnit(),$main_army);UnitScript::joinExisting(new Cavalry(),$main_army);$taxcollector = new TaxCollectionVisitor();$main_army->accept($taxcollector);print $taxcollector->getTax();    //上述的代碼因為太懶沒測試,抱歉! 感興趣的朋友就自己運行調試一下吧!

以上就是PHP訪問者模式與組合模式詳解的詳細內容,更多請關注 其它相關文章!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 攀枝花市| 白河县| 江达县| 宝鸡市| 安泽县| 潍坊市| 丹东市| 东兰县| 台中市| 潜山县| 南部县| 章丘市| 江都市| 胶南市| 尉犁县| 祥云县| 青冈县| 环江| 蓬安县| 剑阁县| 明光市| 双流县| 离岛区| 方城县| 惠东县| 改则县| 新野县| 徐州市| 彩票| 容城县| 垣曲县| 城步| 大姚县| 遂川县| 阿鲁科尔沁旗| 东安县| 班玛县| 亳州市| 建阳市| 樟树市| 关岭|