github地址:https://github.com/ZQCard/design_pattern
/** * 在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。 * 通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。 * 根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。 * 例子:电脑有各个单元组件,设置一个抽象父类,规定具体子类要实现的方法. * 电脑接纳各个组件,并提供访问通道接纳访问者.访问者提出要访问的对象与方法。 */
(1)Computer.class.php (电脑类)
<?php namespace Visitor; class Computer { protected $_items = []; public function add(Unit $unit) { $this->_items[] = $unit; } public function accept(Visitor $visitor) { foreach ($this->_items as $item) { $item->accept($visitor); } } }
(2)Unit.class.php (组件抽象父类)
<?php namespace Visitor; abstract class Unit { public abstract function getName(); public function accept(Visitor $visitor) { $class = get_class($this); $classPath = explode('\',$class); $className = array_pop($classPath); $method = 'visit'.$className; if (method_exists($visitor, $method)){ $visitor->$method($this); echo '<br/>'; } } }
(3)Cpu.class.php (具体组件:cpu)
<?php namespace Visitor; class Cpu extends Unit { public function getName() { return 'i am cpu'; } }
(4)Memory.class.php(具体组件:内存)
<?php namespace Visitor; class Memory extends Unit { public function getName() { return 'i am Memory'; } }
(5)Keyboard.class.php(具体组件:键盘)
<?php namespace Visitor; class Memory extends Unit { public function getName() { return 'i am Memory'; } }
(6)Visitor.class.php (访问者类)
<?php namespace Visitor; class Visitor { public function visitCpu(Cpu $cpu) { echo "hello, " . $cpu->getName() . " "; } public function visitMemory(Memory $memory) { echo "hello, " . $memory->getName() . " "; } public function visitKeyboard(Keyboard $keyboard) { echo "hello, " . $keyboard->getName() . " "; } }
(7)visitor.php (客户端类)
<?php spl_autoload_register(function ($className){ $className = str_replace('\','/',$className); include $className.".class.php"; }); use VisitorComputer; use VisitorCpu; use VisitorMemory; use VisitorKeyboard; use VisitorVisitor; $computer = new Computer(); $computer->add(new Cpu()); $computer->add(new Memory()); $computer->add(new Keyboard()); $computer->accept(new Visitor());