淺談PHP面向?qū)ο笾L問者模式+組合模式
因?yàn)樵闹醒永m(xù)了組合模式的代碼示例來講訪問者模式 所以這里就合并一起來復(fù)習(xí)了。但主要還是講訪問者模式。顧名思義這個模式會有一個訪問者類,被訪問者類調(diào)用訪問者類的時(shí)候會將自身傳遞給它使用。
直接看代碼:
//被訪問者基類 abstract class Unit { abstract function bombardStrength(); //獲取單位的攻擊力 //這個方法將調(diào)用訪問者類,并將自身傳遞給它 function accept(ArmyVisitor $visitor){ $method = "visit" . get_class($this); $visitor->$method($this); //調(diào)用訪問者類的方法,這里使用了 "visit" . get_class($this) 組成了方法的名稱 } //按原文的說法是設(shè)置一個深度,雖然之后會有調(diào)用但這個方法對于理解這個模式不重要可以不用管他(原文示例代碼中經(jīng)常有些跟理解模式原理沒太多關(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)樯鲜龅娜齻€類已經(jīng)是最小單位了不是一個軍事集團(tuán)removeUnit和addUnit方法對他們沒用。 abstract class CompositeUnit extends Unit{ private $units = array(); //存放任何繼承了unit 類的實(shí)例 function getComposite(){ //這個方法主要用于判斷當(dāng)前實(shí)例是否是一個 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){ //調(diào)用訪問者 parent::accept($visitor); foreach($this->units as $thisunit){ $thisunit->accept($visitor); } } } class Army extends CompositeUnit { } class TroopCarrier extends CompositeUnit { } //訪問者類 abstract class ArmyVisitor{ abstract function visit(Unit $node); //訪問者要執(zhí)行的業(yè)務(wù)邏輯 function visitArcher(Archer $node){ //其實(shí)我覺得對于理解來說這個抽象類有一個抽象方法visit()就夠了,原文還多出下面這些方法來繞個圈調(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); } } //這個訪問者類主要用于獲取并保存被訪問者對象的信息 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; } } class TaxCollectionVisitor extends ArmyVisitor{ private $due=0; private $report =""; function visit(Unit $node){ $this->levy($node,1); } function visitArcher(Archer $node){ //復(fù)寫了父類的方法,對于不同的單位征收不同的稅 $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(獲取并輸出每個對象的一些信息) 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(); $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)樘珣袥]測試,抱歉! 感興趣的朋友就自己運(yùn)行調(diào)試一下吧!
以上這篇淺談PHP面向?qū)ο笾L問者模式+組合模式就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
php實(shí)現(xiàn)微信支付之現(xiàn)金紅包
這篇文章主要為大家詳細(xì)介紹了php實(shí)現(xiàn)微信支付之現(xiàn)金紅包,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Yii CDBCriteria常用方法實(shí)例小結(jié)
這篇文章主要介紹了Yii CDBCriteria常用方法,結(jié)合實(shí)例形式總結(jié)分析了CDBCriteria類的功能與常用方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2017-01-01thinkPHP顯示不出驗(yàn)證碼的原因與解決方法分析
這篇文章主要介紹了thinkPHP顯示不出驗(yàn)證碼的原因與解決方法,結(jié)合具體實(shí)例形式分析了thinkPHP關(guān)于驗(yàn)證碼顯示的相關(guān)配置方法與注意事項(xiàng),需要的朋友可以參考下2017-05-05php項(xiàng)目接入xxl-job調(diào)度系統(tǒng)的示例詳解
這篇文章主要介紹了php項(xiàng)目接入xxl-job調(diào)度系統(tǒng)的示例代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12PHP使用openssl擴(kuò)展實(shí)現(xiàn)加解密方法示例
這篇文章主要介紹了PHP使用openssl擴(kuò)展實(shí)現(xiàn)加解密方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02PHP使用Session遇到的一個Permission denied Notice解決辦法
這篇文章主要介紹了PHP使用Session遇到的一個Permission denied Notice解決辦法,本文系統(tǒng)環(huán)境是ubuntu、Debian系統(tǒng),有很小的概率會遇到這個提示,需要的朋友可以參考下2014-07-07thinkPHP5框架實(shí)現(xiàn)基于ajax的分頁功能示例
這篇文章主要介紹了thinkPHP5框架實(shí)現(xiàn)基于ajax的分頁功能,結(jié)合實(shí)例形式分析了thinkPHP5框架上進(jìn)行ajax分頁操作的具體步驟、實(shí)現(xiàn)代碼與相關(guān)操作方法,需要的朋友可以參考下2018-06-06