访问者模式解决的问题
在我们的代码编写过程当中,经常需要对一些类似的对象添加一些的代码,我们以一个计算机对象打印组成部分为例来看下:
/** * 抽象基类 */ abstract class Unit { /** *获取名称 */ abstract public function getName(); } /** * Cpu类 */ class Cpu extends Unit { public function getName() { return 'i am cpu'; } } /** * 内存类 */ class Memory extends Unit { public function getName() { return 'i am memory'; } } /** * 键盘类 */ class Keyboard extends Unit { public function getName() { return 'i am keyboard'; } } /** * 计算机类 */ class Computer { protected $_items = []; public function add(Unit $unit) { $this->_items[] = $unit; } public function print() { // 循环打印各个组成部分 foreach ($this->_items as $item) { $item->getName(); } } }
这个时候上面的代码看上去好像很完美的样子,但是问题来了,现在我们不但需要打印组成部分,还需要保存各个组件到数据库,不仅如此,还需要打印各个组件的价格;此时如果在Unit基类中添加getPrice()和save()方法,也能实现我们想要的功能,但是这样做也存在问题,你并不知道还需要新增什么操作,如果每新增一个操作都用这样的方法来新增,我们的类会变得越来越臃肿。
访问者模式的实现
而访问者模式就是为了解决这个问题的,他把数据结构和作用于结构之上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化,我们来看下面改良过得代码:
/** * 抽象基类 */ abstract class Unit { /** * 获取名称 */ abstract public function getName(); /** * 用来接受访问者对象,回调访问者的visit方法 * 非常关键的方法 */ public function accept(Visitor $visitor) { $method = visit . get_class($this); if (method_exists($visitor, $method)) { $visitor->$method($this); } } } /** * Cpu类 */ class Cpu extends Unit { public function getName() { return 'i am cpu'; } } /** * Memory类 */ class Memory extends Unit { public function getName() { return 'i am memory'; } } /** * Keyboard类 */ class Keyboard extends Unit { public function getName() { return 'i am keyboard'; } } /** * Keyboard类 */ interface Visitor { public function visitCpu(Cpu $cpu); public function visitMemory(Memory $memory); public function visitKeyboard(Keyboard $keyboard); } /** * */ class PrintVisitor implements Visitor { public function visitCpu(Cpu $cpu) { echo "hello, " . $cpu->getName() . "\n"; } public function visitMemory(Memory $memory) { echo "hello, " . $memory->getName() . "\n"; } public function visitKeyboard(Keyboard $keyboard) { echo "hello, " . $keyboard->getName() . "\n"; } } /** * */ class Computer { protected $_items = []; public function add(Unit $unit) { $this->_items[] = $unit; } /** * 调用各个组件的accept方法 */ public function accept(Visitor $visitor) { foreach ($this->_items as $item) { $item->accept($visitor); } } } $computer = new Computer(); $computer->add(new Cpu()); $computer->add(new Memory()); $computer->add(new Keyboard()); $printVisitor = new PrintVisitor(); $computer->print($printVisitor); // 以上的代码将打印出 hello, i am cpu hello, i am memory hello, i am keyboard
总结
经过上面的改良之后,我们要扩展就变得非常容易,如果我们需要新增保存到数据库的方法,可以在新增一个实现了Visitor的类,比如SaveVisitor,在该类中来实现保存的方法,等于我们把该类和该类中的一些操作解藕了出来,而集合了类操作的对象就是访问者。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
风云阁资源网 Design By www.bgabc.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
风云阁资源网 Design By www.bgabc.com
暂无评论...
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
2024年09月26日
2024年09月26日
- 纯音入心系列纯音乐《中央民族乐团-古筝传奇》1CD[MP3][253.1MB]
- 江玲.1989-这样你才爱我,是吗?【新作有声】【WAV+CUE】
- 郭美美.2010-我是郭美美【华纳】【WAV+CUE】
- 黄心懋1991-轻忧郁【滚石】【WAV+CUE】
- 群星.2000-大地金曲世纪回顾2CD【大地】【WAV+CUE】
- 王菲.1996-浮躁(2024环球MQA-UHQCD限量版)【环球】【WAV+CUE】
- 群星.2022-传家电视剧原声带【东阳欢娱】【FLAC分轨】
- 《摇滚教父 伍佰黄金精选 2CD》 [WAV+CUE][1GB]
- 《凤凰传奇 我从草原来》[WAV/分轨][400MB]
- 《叶倩文 真心真意过一生》[WAV+CUE][400MB]
- 潘越云.1985-世间女子(滚石25周年经典复刻版)【滚石】【WAV+CUE】
- 陈柏宇.2009-CANT.BE.HALF【SONY】【WAV+CUE】
- 李明依.1989-小女生【滚石】【WAV+CUE】
- 《李荣浩 新时代创作新人王》[WAV分轨][310MB]
- 《黑鸭子与马头琴 史上最动听草原音乐》[WAV+CUE][320MB]