PHP面向对象中的访问者模式和组合模式的用法
发表于:2025-01-17 作者:千家信息网编辑
千家信息网最后更新 2025年01月17日,本篇内容主要讲解"PHP面向对象中的访问者模式和组合模式的用法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"PHP面向对象中的访问者模式和组合模式的用法"
千家信息网最后更新 2025年01月17日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面向对象中的访问者模式和组合模式的用法"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
方法
访问者
代码
模式
对象
单位
军事
客户
客户端
组合
信息
原文
实例
不同
业务
兴趣
内容
弓箭
弓箭手
攻击力
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
数据库文件导入出错
数据库加工处理流程
湘潭快速软件开发中介
停车场软件开发商
网络安全信息建议
软件开发面经
12123郑州服务器
软件开发版本管理流程
软件开发行业公司图片
轻量数据库对比
单行数据库
网络安全跟网络工程一样吗
设计数据库的时间 长度
河北睿旭网络技术有限公司
服务器系统光盘
哪些服务器架设在国外的网址
易语言db数据库
软微网络安全李鼎
华为对蜂窝网络技术的贡献
政治学科活动网络安全素材
迁安市网络安全专题培训
关注网络安全 建设活动
pdu服务器电源价格表
网络安全设备测试拓扑
大学生如何树立网络安全意识论文
杭州公安局网络安全专业测试
洛阳工匠软件开发有限公司电话
20000g的私有云服务器
为什么卡巴斯基数据库更新不了
java软件开发课