php实例-浅谈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实例-浅谈PHP面向对象之访问者模式+组合模式的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

PHP 8.4 带来了多项新功能、安全性改进和性能改进,同时弃用和删除了大量功能。 本指南介绍了如何在 Ubuntu、Debian 或其衍生版本上安装 PHP 8.4 或升级到 PHP 8.4

CakePHP 是 PHP 的开源框架。它的目的是使应用程序的开发、部署和维护变得更加容易。 CakePHP 基于类似 MVC 的架构,功能强大且易于掌握。模型、视图和控制器 gu

登录 CakePHP 是一项非常简单的任务。您只需使用一项功能即可。您可以记录任何后台进程(如 cronjob)的错误、异常、用户活动、用户采取的操作。在 CakePHP 中记录数据很容易。提供了 log() 函数

Visual Studio Code,也称为 VS Code,是一个免费的源代码编辑器 - 或集成开发环境 (IDE) - 可用于所有主要操作系统。 VS Code 拥有针对多种编程语言的大量扩展,可以轻松编写
