定义
访问者模式(Visitor Pattern)表示一个作用于对象结构中的各元素的操作,它使的客户端在不改变各元素类的前提下定义作用于这些元素的新操作,属于行为型模式。
代码示例
按通俗的时间划分规则,一天中只分为白天和夜里,在这两天不同的时间段内,做事情都会有不同的状态。抽象出当天的对象OneDay,用白天Day和晚上Night 的类具体实现当天的对象,通过刷牙类和工作类充当访问者,来实现不同时间段做事情产生不同的状态。
当天对象的方法accept 里实现了一种 ”双分派“ 技术,首先客户端将访问者visitor传入,再通过传入自己$this 作为参数,完成第二次分派。
<?php
abstract class OneDay
{
abstract public function accept($visitor);
}
class Day extends OneDay
{
public $notice = '白天';
public function accept($visitor)
{
return $visitor->planForDay($this);
}
}
class Night extends OneDay
{
public $notice = '晚上';
public function accept($visitor)
{
return $visitor->planForNight($this);
}
}
abstract class Plan
{
abstract public function planForDay($element);
abstract public function planForNight($element);
}
class BrushTeeth extends Plan
{
public function planForDay($element)
{
echo $element->notice .'需要刷牙' . '<br>';
}
public function planForNight($element)
{
echo $element->notice .'需要刷牙' . '<br>';
}
}
class Work extends Plan
{
public function planForDay($element)
{
echo $element->notice .'需要工作' . '<br>';
}
public function planForNight($element)
{
echo $element->notice . '需要睡觉' . '<br>';
}
}
class ActionPlan
{
private $planList = [];
public function add($element)
{
$this->planList[] = $element;
}
public function accept($visitor)
{
foreach($this->planList as $key => $item){
$item->accept($visitor);
}
}
}
class DemoPattern
{
public function handle()
{
$actionPlan = new ActionPlan();
$actionPlan->add(new Day());
$actionPlan->add(new Night());
$brushTeeth = new BrushTeeth();
$work = new Work();
$actionPlan->accept($brushTeeth);
$actionPlan->accept($work);
}
}
$demoPattern = new DemoPattern();
$demoPattern->handle();
总结
访问者模式适用于数据结构相对稳定的系统,它把数据结构和作用于结构之上的操作之间的耦合解开了,使得操作集合可以相对自由地演化。对于变动频繁的系统,则不适应此模式。
网友评论