您好,登錄后才能下訂單哦!
本篇內容主要講解“PHP面向對象中的訪問者模式和組合模式的用法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“PHP面向對象中的訪問者模式和組合模式的用法”吧!
直接看代碼:
//被訪問者基類 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面向對象中的訪問者模式和組合模式的用法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。