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 '
'; } } }
(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 (访问者类)
getName() . "\n";
}
public function visitMemory(Memory $memory)
{
echo "hello, " . $memory->getName() . "\n";
}
public function visitKeyboard(Keyboard $keyboard)
{
echo "hello, " . $keyboard->getName() . "\n";
}
}
(7)visitor.php (客户端类)
php spl_autoload_register(function ($className){ $className = str_replace('\\','/',$className); include $className.".class.php"; }); use Visitor\Computer; use Visitor\Cpu; use Visitor\Memory; use Visitor\Keyboard; use Visitor\Visitor; $computer = new Computer(); $computer->add(new Cpu()); $computer->add(new Memory()); $computer->add(new Keyboard()); $computer->accept(new Visitor());