访问者模式是一种行为型模式,访问者表示一个作用于某对象结构中各元素的操作。它可以在不修改各元素类的前提下定义作用于这些元素的新操作,即动态的增加具体访问者角色。

访问者模式利用了双重分派。先将访问者传入元素对象的Accept方法中,然后元素对象再将自己传入访问者,之后访问者执行元素的相应方法。

主要角色

抽象访问者角色(Visitor):为该对象结构(ObjectStructure)中的每一个具体元素提供一个访问操作接口。该操作接口的名字和参数标识了 要访问的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。
具体访问者角色(ConcreteVisitor):实现抽象访问者角色接口中针对各个具体元素角色声明的操作。
抽象节点(Node)角色:该接口定义一个accept操作接受具体的访问者。
具体节点(Node)角色:实现抽象节点角色中的accept操作。

对象结构角色(ObjectStructure):这是使用访问者模式必备的角色。它要具备以下特征:能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序集合(在PHP中我们使用数组代替,因为PHP中的数组本来就是一个可以放置任何类型数据的集合)
适用性

访问者模式多用在聚集类型多样的情况下。在普通的形式下必须判断每个元素是属于什么类型然后进行相应的操作,从而诞生出冗长的条件转移语句。而访问者模式则可以比较好的解决这个问题。对每个元素统一调用element−>accept(vistor)即可。
访问者模式多用于被访问的类结构比较稳定的情况下,即不会随便添加子类。访问者模式允许被访问结构添加新的方法。

<?php
interface Visitor { // 抽象访问者角色
public function visitConcreteElementA(ConcreteElementA $elementA);
public function visitConcreteElementB(concreteElementB $elementB);
} interface Element { // 抽象节点角色
public function accept(Visitor $visitor);
} class ConcreteVisitor1 implements Visitor { // 具体的访问者1
public function visitConcreteElementA(ConcreteElementA $elementA) {}
public function visitConcreteElementB(ConcreteElementB $elementB) {}
} class ConcreteVisitor2 implements Visitor { // 具体的访问者2
public function visitConcreteElementA(ConcreteElementA $elementA) {}
public function visitConcreteElementB(ConcreteElementB $elementB) {}
} class ConcreteElementA implements Element { // 具体元素A
private $_name;
public function __construct($name) { $this->_name = $name; }
public function getName() { return $this->_name; }
public function accept(Visitor $visitor) { // 接受访问者调用它针对该元素的新方法
$visitor->visitConcreteElementA($this);
}
} class ConcreteElementB implements Element { // 具体元素B
private $_name;
public function __construct($name) { $this->_name = $name;}
public function getName() { return $this->_name; }
public function accept(Visitor $visitor) { // 接受访问者调用它针对该元素的新方法
$visitor->visitConcreteElementB($this);
}
} class ObjectStructure { // 对象结构 即元素的集合
private $_collection;
public function __construct() { $this->_collection = array(); }
public function attach(Element $element) {
return array_push($this->_collection, $element);
}
public function detach(Element $element) {
$index = array_search($element, $this->_collection);
if ($index !== FALSE) {
unset($this->_collection[$index]);
}
return $index;
}
public function accept(Visitor $visitor) {
foreach ($this->_collection as $element) {
$element->accept($visitor);
}
}
} // client
$elementA = new ConcreteElementA("ElementA");
$elementB = new ConcreteElementB("ElementB");
$elementA2 = new ConcreteElementB("ElementA2");
$visitor1 = new ConcreteVisitor1();
$visitor2 = new ConcreteVisitor2(); $os = new ObjectStructure();
$os->attach($elementA);
$os->attach($elementB);
$os->attach($elementA2);
$os->detach($elementA);
$os->accept($visitor1);
$os->accept($visitor2);

PHP设计模式 - 访问者模式的更多相关文章

  1. .NET设计模式访问者模式

    一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...

  2. C#设计模式-访问者模式

    一. 访问者(Vistor)模式 访问者模式是封装一些施加于某种数据结构之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保存不变.访问者模式适用于数据结构相对稳定的系统, 它把数据结 ...

  3. JAVA 设计模式 访问者模式

    用途 访问者模式 (Visitor) 表示一个作用于某对象结构中的各元素的操作. 它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 访问者模式是一种行为型模式. 用途

  4. 深入浅出设计模式——访问者模式(Visitor Pattern)

    模式动机 对于系统中的某些对象,它们存储在同一个集合中,且具有不同的类型,而且对于该集合中的对象,可以接受一类称为访问者的对象来访问,而且不同的访问者其访问方式有所不同,访问者模式为解决这类问题而诞生 ...

  5. java设计模式---访问者模式

      Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自 己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广 泛,遵循一定的编程模式,才能使自 ...

  6. C++设计模式——访问者模式

    访问者模式 在GOF的<设计模式:可复用面向对象软件的基础>一书中对访问者模式是这样说的:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的 ...

  7. 设计模式 -- 访问者模式(Visitor)

    写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------主要内容包括: 初识访问者模 ...

  8. Java设计模式—访问者模式

    原文地址:http://www.cnblogs.com/java-my-life/archive/2012/06/14/2545381.html 总结的太棒啦,导致自己看了都不想总结了...... 在 ...

  9. C#设计模式——访问者模式(Visitor Pattern)

    一.概述由于需求的改变,某些类常常需要增加新的功能,但由于种种原因这些类层次必须保持稳定,不允许开发人员随意修改.对此,访问者模式可以在不更改类层次结构的前提下透明的为各个类动态添加新的功能.二.访问 ...

  10. Java设计模式-访问者模式(Visitor)

    访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化.访问者模式适用于数据结构相对稳定算法又易变化的系统.因为访问者模式使得算法操作增加变得容易.若系统数据结构对象易于变化,经 ...

随机推荐

  1. idea中隐藏.iml文件

    在创建父子工程或者聚合工程时产生的大量 .iml 文件,有时会对我们的操作产生干扰,所以,一般情况下,我们都将其隐藏掉,步骤如下: File——>settings——>Editor——&g ...

  2. Wooden Signs Gym - 101128E (DP)

    Problem E: Wooden Signs \[ Time Limit: 1 s \quad Memory Limit: 256 MiB \] 题意 给出一个\(n\),接下来\(n+1\)个数, ...

  3. Numpy | 12 数组操作

    Numpy 中包含了一些函数用于处理数组,大概可分为以下几类: 修改数组形状 翻转数组 修改数组维度 连接数组 分割数组 数组元素的添加与删除 一.修改数组形状 函数 描述 reshape 不改变数据 ...

  4. 常用方法 Excel转换为DataSet

    注意一下Excel格式,我平时导入的是xlsx /// <summary> /// Excel 转换为 DataSet /// </summary> /// <param ...

  5. 【JZOJ6230】【20190625】梦批糼

    题目 一个$n\times m \times l $的立方体,有一些位置有障碍 一次操作会随机选择一个立方体,共有\(w\)次操作 询问所有操作都不选到障碍点,被选到至少一次的点的期望 $n ,m,l ...

  6. mysql初始

    数据(data) : -描述事物的符号记录称为数据,符号既可以是数据,文字,图片,声音,语言等,符号都可以经过数字化后存入计算机中 - 计算机中描述一个事物,就需要抽取这一事物的典型特征,组成一条记录 ...

  7. socket数据传输

    目录 subprocess模块 struct模块: 粘包问题: QQ聊天的实现: 文件的传输: 大文件的传输: 传输层协议: TCP : UDP: FTP: socketServer模块: subpr ...

  8. http 缓存机制简介

    我们应该从两个角度来看http的缓存:缓存控制 和 缓存校验.缓存控制:控制缓存的开关,用于标识请求或访问中是否开启了缓存,使用了什么样的存方式.缓存校验:如何校验缓存,缓存的有效期,如何确定缓存是最 ...

  9. linux高性能服务器编程 (七) --Linux服务器程序规范

    第七章 LInux 服务器程序规范 1)linux服务器程序一般以后台进程形式运行.后台进程又称为守护进程,是没有控制终端的,所以不会受到外界的干扰.守护进程的父进程通常是init进程(PID为1的进 ...

  10. saltstack自动化运维工具搭建个人笔记

    至于为什么选择saltstack,因为Puppet.Chef基于Ruby开发,而ansible.saltstack基于python开发,便于后期二次,良好的可移植性. 又,ansible基于SSH协议 ...