声明:本系列博客參考资料《大话设计模式》,作者程杰。

訪问者模式表示一个作用于某对象结构中的各元素的操作。

它使你能够在不改变各元素类的前提下定义作用于这些元素的新操作。

UML类图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamhxMDExMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

角色:

1.抽象訪问者(State):为该对象结构中详细元素角色声明一个訪问操作接口。

该操作接口的名字和參数标识了发送訪问请求给详细訪问者的详细元素角色,这样訪问者就能够通过该元素角色的特定接口直接訪问它。

2.详细訪问者(Success):实现訪问者声明的接口。

3.抽象元素(Person):定义一个接受訪问操作accept(),它以一个訪问者作为參数。

4. 详细元素(Man):实现了抽象元素所定义的接受操作接口。

5.结构对象(ObjectStruct):这是使用訪问者模式必备的角色。

它具备下面特性:能枚举它的元素。能够提供一个高层接口以同意訪问者訪问它的元素;如有须要,能够设计成一个复合对象或者一个聚集(如一个列表或无序集合)。

核心代码:

<span style="color:#000000;"><?php
/**
* Created by PhpStorm.
* User:Jang
* Date:2015/6/11
* Tim: 9 :40
*/ /*男人这本书的内容要比封面吸引人;女人这本书的封面通常比内容更吸引人
男人成功时。背后多半有一个伟大的女人;女人成功时,背后多半有一个失败的男人
男人失败时,闷头喝酒,谁也不用劝。女人失败时,眼泪汪汪,谁也劝不了
男人恋爱时,凡事不懂也要装懂。女人恋爱时。遇事懂也要装作不懂*/
//抽象状态
abstract class State
{
protected $state_name; //得到男人反应
public abstract function GetManAction(VMan $elementM);
//得到女人反应
public abstract function GetWomanAction(VWoman $elementW);
} //抽象人
abstract class Person
{
public $type_name; public abstract function Accept(State $visitor);
} //成功状态
class Success extends State
{
public function __construct()
{
$this->state_name="成功";
} public function GetManAction(VMan $elementM)
{
echo "{$elementM->type_name}:{$this->state_name}时,背后多半有一个伟大的女人。<br/>";
} public function GetWomanAction(VWoman $elementW)
{
echo "{$elementW->type_name} :{$this->state_name}时。背后大多有一个不成功的男人。<br/>";
}
} //失败状态
class Failure extends State
{
public function __construct()
{
$this->state_name="失败";
} public function GetManAction(VMan $elementM)
{
echo "{$elementM->type_name}:{$this->state_name}时,闷头喝酒,谁也不用劝。<br/>";
} public function GetWomanAction(VWoman $elementW)
{
echo "{$elementW->type_name} :{$this->state_name}时。眼泪汪汪,谁也劝不了。<br/>";
}
} //恋爱状态
class Amativeness extends State
{
public function __construct()
{
$this->state_name="恋爱";
} public function GetManAction(VMan $elementM)
{
echo "{$elementM->type_name}:{$this->state_name}时,凡事不懂也要装懂。<br/>";
} public function GetWomanAction(VWoman $elementW)
{
echo "{$elementW->type_name} :{$this->state_name}时,遇事懂也要装作不懂。<br/>";
}
} //男人
class VMan extends Person
{
function __construct()
{
$this->type_name="男人";
} public function Accept(State $visitor)
{
$visitor->GetManAction($this);
}
} //女人
class VWoman extends Person
{
public function __construct()
{
$this->type_name="女人";
} public function Accept(State $visitor)
{
$visitor->GetWomanAction($this);
}
} //对象结构
class ObjectStruct
{
private $elements=array();
//添加
public function Add(Person $element)
{
array_push($this->elements,$element);
}
//移除
public function Remove(Person $element)
{
foreach($this->elements as $k=>$v)
{
if($v==$element)
{
unset($this->elements[$k]);
}
}
} //查看显示
public function Display(State $visitor)
{
foreach ($this->elements as $v)
{
$v->Accept($visitor);
}
}
}</span>

測试client代码:

header("Content-Type:text/html;charset=utf-8");
//------------------------訪问者模式--------------------
require_once "./Visitor/Visitor.php";
$os = new ObjectStruct();
$os->Add(new VMan());
$os->Add(new VWoman()); //成功时反应
$ss = new Success();
$os->Display($ss); //失败时反应
$fs = new Failure();
$os->Display($fs); //恋爱时反应
$ats=new Amativeness();
$os->Display($ats);

适用场景及优势:

1) 一个对象结构包括非常多类对象。它们有不同的接口,而你想对这些对象实施一些依赖于其详细类的操作。

2) 须要对一个对象结构中的对象进行非常多不同的而且不相关的操作。而你想避免让这些操作“污染”这些对象的类。

Visitor模式使得你能够将相关的操作集中起来定义在一个类中。

3) 当该对象结构被非常多应用共享时,用Visitor模式让每一个应用仅包括须要用到的操作。

4) 定义对象结构的类非常少改变。但常常须要在此结构上定义新的操作。

改变对象结构类须要重定义对全部訪问者的接口,这可能须要非常大的代价。

假设对象结构类常常改变。那么可能还是在这些类中定义这些操作较好。

欢迎关注我的视频课程。地址例如以下,谢谢。

PHP面向对象设计模式

最新文章

  1. CentOS Mono Nginx 部署 MVC4+WebApi
  2. linux 时间管理——概念、注意点(一)【转】
  3. Tomcat启动,不能加载项目问题。
  4. UVA1213Sum of Different Primes(素数打表 + DP)
  5. LayaAir引擎——(一)
  6. [Python爬虫] Selenium实现自动登录163邮箱和Locating Elements介绍
  7. 怎样从命令行进入mac桌面
  8. Linux下进程的创建
  9. web02--jsp数据传递
  10. ubuntu 下添加sublime text 启动图标
  11. express学习点滴- session()和cookieSession()的区别
  12. js、JSP、servlet之间的传递小结
  13. 五年级--python函数高级运用
  14. Django---forms表单使用(1)
  15. 【Linux】使用Google Authenticator 实现ssh登录双因素认证
  16. 《R数据挖掘入门》彩色插图(第8章)
  17. crontab入门
  18. HTML5制作简单画板
  19. java中Object转换成int或String类型方法
  20. 洛谷3805:【模板】manacher算法——题解

热门文章

  1. 敏捷开发的道与术---MPD软件工作坊培训感想(上)
  2. vs2015 停 在 update kb2999226 一直不动
  3. android:首页点击返回键,两秒内再次点击退出系统
  4. VMware 15 安装 MAC OS 10.13 原版(详细图文教程)
  5. Android--将实体类转化成Json和Map的基类
  6. [Android] 针对生成的图片文件在系统Gallery不显示的处理
  7. Android 获取系统语言(兼容7.0)
  8. 【SPL标准库专题(9)】 Datastructures:SplObjectStorage
  9. 树莓派Pi2 使用入门
  10. 为何SQL SERVER使用sa账号登录还原数据库BAK文件失败,但是使用windows登录就可以