访问者模式(Visitor、Element、accept、ObjectStructure、)(操作外置,与数据结构分离)
访问者模式表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
从定义可以看出结构对象是使用访问者模式的必备条件,而且这个结构对象必须存在遍历自身各个对象的方法,类似于Java中的Collection。
访问者模式的目的是要把处理从数据结构中分离出来,如果系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式是个不错的选择,因为访问者模式使的算法操作的增加变得容易。相反,如果系统的数据结构不稳定,易于变化,则此系统就不适合使用访问者模式了。
类图:

访问者模式结构:
访问者角色(Visitor): 为该对象结构中具体元素角色声明一个访问操作接口.
具体访问者角色(Concrete Visitor): 实现每个由访问者角色(Visitor)声明的操作.
元素角色(Element): 定义一个Accept操作,它以一个访问者为参数.
具体元素角色(Concrete Element): 实现由元素角色提供的Accept操作.
对象结构角色(Object Structure): 这是使用访问者模式必备的角色. 它要具备以下特征: 能枚举它的元素; 可以提供一个高层的接口以允许该访问者访问它的元素; 可以是一个复合(组合模式)或是一个集合, 如一个列表或一个无序集合.
实例:
public interface Visitor
{
public void visit(GladiolusConcreteElement gladiolus);
public void visit(ChrysanthemumConreteElement chrysanthemum);
}
public interface FlowerElement
{
public void accept(Visitor visitor);
}
public class GladiolusConcreteElement implements FlowerElement
{
@Override
public void accept(final Visitor visitor)
{
visitor.visit(this);
}
}
public class ChrysanthemumConreteElement implements FlowerElement
{
@Override
public void accept(final Visitor visitor)
{
visitor.visit(this);
}
}
public class GladiolusVisitor implements Visitor
{
@Override
public void visit(final GladiolusConcreteElement gladiolus)
{
System.out.println(this.getClass().getSimpleName() + " access " + gladiolus.getClass().getSimpleName());
}
@Override
public void visit(final ChrysanthemumConreteElement chrysanthemum)
{
System.out.println(this.getClass().getSimpleName() + " access " + chrysanthemum.getClass().getSimpleName());
}
}
public class ChrysanthemumConreteElement implements FlowerElement
{
@Override
public void accept(final Visitor visitor)
{
visitor.visit(this);
}
}
public class ObjectStructure
{
private final List<FlowerElement> elements = new ArrayList<FlowerElement>();
public void addElement(final FlowerElement e)
{
elements.add(e);
}
public void removeElement(final FlowerElement e)
{
elements.remove(e);
}
public void accept(final Visitor visitor)
{
for (final FlowerElement e : elements)
{
e.accept(visitor);
}
}
}
public class Client
{
public static void main(final String[] args)
{
final ObjectStructure os = new ObjectStructure();
os.addElement(new GladiolusConcreteElement());
os.addElement(new ChrysanthemumConreteElement());
final GladiolusVisitor gVisitor = new GladiolusVisitor();
final ChrysanthemumVisitor chVisitor = new ChrysanthemumVisitor();
os.accept(gVisitor);
os.accept(chVisitor);
}
}
运行结果:
GladiolusVisitor access GladiolusConcreteElement
GladiolusVisitor access ChrysanthemumConreteElement
ChrysanthemumVisitor access GladiolusConcreteElement
ChrysanthemumVisitor access ChrysanthemumConreteElement
访问者模式(Visitor、Element、accept、ObjectStructure、)(操作外置,与数据结构分离)的更多相关文章
- 访问者模式(Visitor Pattern)——操作复杂对象结构
模式概述 在软件开发中,可能会遇到操作复杂对象结构的场景,在该对象结构中存储了多个不同类型的对象信息,而且对同一对象结构中的元素的操作方式并不唯一,可能需要提供多种不同的处理方式,还有可能增加新的处理 ...
- [设计模式] 23 访问者模式 visitor Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对访问者模式是这样说的:表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.访问 ...
- 设计模式 ( 二十 ) 访问者模式Visitor(对象行为型)
设计模式 ( 二十 ) 访问者模式Visitor(对象行为型) 1.概述 在软件开发过程中,对于系统中的某些对象,它们存储在同一个集合collection中,且具有不同的类型,而且对于该集合中的对象, ...
- 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern)
原文:乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) 作者:webabc ...
- 访问者模式 Visitor 行为型 设计模式(二十七)
访问者模式 Visitor <侠客行>是当代作家金庸创作的长篇武侠小说,新版电视剧<侠客行>中,开篇有一段独白: “茫茫海外,传说有座侠客岛,岛上赏善罚恶二使,每隔十年 ...
- 二十四种设计模式:访问者模式(Visitor Pattern)
访问者模式(Visitor Pattern) 介绍表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作. 示例有一个Message实体类,某些对象对 ...
- 十一个行为模式之访问者模式(Visitor Pattern)
定义: 提供一个作用于某对象结构(通常是一个对象集合)的操作的接口,使得在添加新的操作或者在添加新的元素时,不需要修改原有系统,就可以对各个对象进行操作. 结构图: Visitor:抽象访问者类,对元 ...
- C#设计模式——访问者模式(Visitor Pattern)
一.概述由于需求的改变,某些类常常需要增加新的功能,但由于种种原因这些类层次必须保持稳定,不允许开发人员随意修改.对此,访问者模式可以在不更改类层次结构的前提下透明的为各个类动态添加新的功能.二.访问 ...
- 设计模式 -- 访问者模式(Visitor)
写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------主要内容包括: 初识访问者模 ...
随机推荐
- Spring Boot 整合 ActiveMQ
依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spri ...
- Python操作MySQL以及数据库索引
目录 python操作MySQL 安装 使用 SQL注入问题 MySQL的索引 为什么使用索引 索引的种类 主键索引 唯一索引 普通索引 索引优缺点 不会命中索引的情况 explain 索引覆盖 My ...
- linux和window环境下安装ruby和sass
linux下安装ruby 下载linux的ruby安装包 http://www.ruby-lang.org/en/downloads/ 将ruby安装包在linux环境下解压 tar -x ...
- PHP接收数据数据包的几个方式
PHP默认识别的数据类型是application/x-www.form-urlencoded标准的数据类型. php获取post参数的几种方式 1.$_POST['paramName'] 只能接收Co ...
- Android 之 BroadcaseReceiver
1.在AndroidManifest.xml中注册 <receiver android:name=".MyReceiver"> <intent-filter &g ...
- codeforces 1100E-Andrew and Taxi
传送门:QAQQAQ 题意:给你一个图,每条边有边权,现在你可以对边进行反转,使图中不存在环,你需要使得反转的边的边权集合中的最大值最小,并输出任意一组解. 思路:二分+拓扑排序 使得最大值最小,自然 ...
- <每日一题>题目10:求斐波拉契数列
def func(x): m,n = 0,1 i = 0 while i < x: yield m m,n = n,m+n i += 1 fib = [] get_func = func(100 ...
- Image 转换成 Icon
/// <summary> /// Converts an image into an icon. /// </summary> /// <param name=&quo ...
- js 实现横向轮播效果
参考:https://www.cnblogs.com/LIUYANZUO/p/5679753.html html: <!DOCTYPE html> <html> <hea ...
- java笔试之数字颠倒
描述: 输入一个整数,将这个整数以字符串的形式逆序输出 程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001 package test; import java.ut ...