CleverCode最近在看访问者模式。
1 模式介绍
封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作
2 模式中的角色
1.Visitor 抽象访问者角色,为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它。
2.ConcreteVisitor.具体访问者角色,实现Visitor声明的接口。
3.Element 定义一个接受访问操作(accept()),它以一个访问者(Visitor)作为参数。
4.ConcreteElement 具体元素,实现了抽象元素(Element)所定义的接受操作接口。
5.ObjectStructure 结构对象角色,这是使用访问者模式必备的角色。它具备以下特性:能枚举它的元素;可以提供一个高层接口以允许访问者访问它的元素;如有需要,可以设计成一个复合对象或者一个聚集(如一个列表或无序集合)。
3 模式结构
4 项目
4.1 设计一个不同的人喜欢喝不同的茶的场景
4.2 源码设计
<?php
/**
* php访问者模式
* copyright http://blog.csdn.net/CleverCode
*
*/
//定义访问者接口
abstract class TeaVisitor
{/*{{{*/
//和红茶
abstract function redTea(Person $person);
//喝绿茶
abstract function greenTea(Person $person);
}/*}}}*/
class DrinkTeaVisitor extends TeaVisitor
{/*{{{*/
//和红茶
function redTea(Person $person)
{
$person->drink('红茶');
}
//喝绿茶
function greenTea(Person $person)
{
$person->drink('绿茶');
}
}/*}}}*/
//定义元素接口
abstract class Person
{/*{{{*/
abstract function dreakTea(TeaVisitor $vitor);
public function drink($name)
{
echo "喝 {$name}\r\n";
}
}/*}}}*/
//实现元素接口
class PersonA extends Person
{/*{{{*/
function dreakTea(TeaVisitor $vitor)
{
$vitor->redTea($this);
}
}/*}}}*/
class PersonB extends Person
{/*{{{*/
function dreakTea(TeaVisitor $vitor)
{
$vitor->greenTea($this);
}
}/*}}}*/
//用户的树形结构
class Persons
{/*{{{*/
protected $persons = array();
public function addPerson(Person $person)
{
$this->persons[] = $person;
}
//让所有的用户都能被访问者访问
public function handleVisitor(TeaVisitor $visitor)
{
foreach($this->persons as $user)
{
$user->dreakTea($visitor);
}
}
}/*}}}*/
class Client
{
public static function main($argv)
{
$persons = new Persons();
$persons->addPerson(new PersonA());
$persons->addPerson(new PersonB());
$drinkTeaVisitor = new DrinkTeaVisitor();
$persons->handleVisitor($drinkTeaVisitor);
}
}
Client::main($argv);
?>
4.3 结果展示
技术交流
CleverCode是一名架构师,技术交流,咨询问题,请加CleverCode创建的qq群(架构师俱乐部):517133582。加群和腾讯,阿里,百度,新浪等公司的架构师交流。【架构师俱乐部】宗旨:帮助你成长为架构师!