您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“PHP面向?qū)ο笾械脑L問(wèn)者模式和組合模式的用法”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“PHP面向?qū)ο笾械脑L問(wèn)者模式和組合模式的用法”吧!
直接看代碼:
//被訪問(wèn)者基類 abstract class Unit { abstract function bombardStrength(); //獲取單位的攻擊力 //這個(gè)方法將調(diào)用訪問(wèn)者類,并將自身傳遞給它 function accept(ArmyVisitor $visitor){ $method = "visit" . get_class($this); $visitor->$method($this); //調(diào)用訪問(wèn)者類的方法,這里使用了 "visit" . get_class($this) 組成了方法的名稱 } //按原文的說(shuō)法是設(shè)置一個(gè)深度,雖然之后會(huì)有調(diào)用但這個(gè)方法對(duì)于理解這個(gè)模式不重要可以不用管他(原文示例代碼中經(jīng)常有些跟理解模式原理沒(méi)太多關(guān)系的代碼) 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類的實(shí)例,并讓Army和TroopCarrier類繼承removeUnit和addUnit方法,不放基類是因?yàn)樯鲜龅娜齻€(gè)類已經(jīng)是最小單位了不是一個(gè)軍事集團(tuán)removeUnit和addUnit方法對(duì)他們沒(méi)用。 abstract class CompositeUnit extends Unit{ private $units = array(); //存放任何繼承了unit 類的實(shí)例 function getComposite(){ //這個(gè)方法主要用于判斷當(dāng)前實(shí)例是否是一個(gè) CompositeUnit 類 return $this; } protected function units(){ return $this->units; } function removeUnit(Unit $unit){ //刪除一個(gè)軍事單位 $this->units = array_udiff( $this->units,array($unit), function($a,$b){return ($a === $b)?0:1;} ); } function addUnit(Unit $unit){ //添加一個(gè)軍事單位 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){ //調(diào)用訪問(wèn)者 parent::accept($visitor); //調(diào)用基類的accept方法,在第一個(gè)客戶端代碼條用里將會(huì)保存軍事集團(tuán)整體的一個(gè)信息 foreach($this->units as $thisunit){ //調(diào)用軍事單位accept方法,在第一個(gè)客戶端代碼條用里將會(huì)保存其中每一個(gè)軍事單位的信息 $thisunit->accept($visitor); } } } //軍隊(duì) class Army extends CompositeUnit { } //艦隊(duì) class TroopCarrier extends CompositeUnit { } //訪問(wèn)者類 abstract class ArmyVisitor{ abstract function visit(Unit $node); //訪問(wèn)者要執(zhí)行的業(yè)務(wù)邏輯 function visitArcher(Archer $node){ //其實(shí)我覺得對(duì)于理解來(lái)說(shuō)這個(gè)抽象類有一個(gè)抽象方法visit()就夠了,原文還多出下面這些方法來(lái)繞個(gè)圈調(diào)用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); } } //這個(gè)訪問(wèn)者類主要用于獲取并保存被訪問(wèn)者對(duì)象的信息 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; } } //用于向每個(gè)對(duì)象征稅的訪問(wèn)者類,客戶端代碼2中將會(huì)調(diào)用 class TaxCollectionVisitor extends ArmyVisitor{ private $due=0; private $report =""; function visit(Unit $node){ $this->levy($node,1); } function visitArcher(Archer $node){ //復(fù)寫了父類的方法,對(duì)于不同的單位征收不同的稅 $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){ //主要的業(yè)務(wù)邏輯 $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(獲取并輸出每個(gè)對(duì)象的一些信息) 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(對(duì)每個(gè)對(duì)象征稅,最后輸出總共征收了多少) $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(); //上述的代碼因?yàn)樘珣袥](méi)測(cè)試,抱歉! 感興趣的朋友就自己運(yùn)行調(diào)試一下吧!
到此,相信大家對(duì)“PHP面向?qū)ο笾械脑L問(wèn)者模式和組合模式的用法”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。