Java设计模式之访问者模式使用场景及代码示例

Java设计模式访问者模式

模式概念

访问者模式表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。访问者模式适用于数据结构相对稳定算法又易变化的系统,若系统数据结构对象易于变化,则不适合使用访问者模式。访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。

Visitor应用场景

一定会有的疑问:visitor和iterator的区别:

visitor可以访问不同的对象(只需要在Element定义对应的accept),但是Iterator只能访问相同的对象,最起码要有相同的接口
iterator是不依赖具体实现的,而visitor是依赖具体实现的,因为Visitor会根据访问的具体的对象来采取对应的操作,而iterator最多只是基于相同的接口的泛化实现。

iterator访问的数据结构的操作和数据并未分离,所以拓展功能起来需要修改,违反了开闭原则和单一职责原则。但是因为访问者依赖具体实现,而不是依赖抽象,所以违反了依赖倒置原则

优缺点决定的应用场景

符合单一职责原则,功能上具有良好的拓展性,但是因为依赖具体实现违背了具体实现,所以为类的修改带了麻烦。

具有优良的拓展性,只需要实现新的Visitor来满足新的访问要求。因为数据和操作的分离,防止了添加新的操作污染原来的数据结构。

综上

访问者是一种集中规整模式,特别适合用于大规模重构的项目,在这一个阶段的需求已经非常清晰,原系统的功能点也已经明确,通过访问者模式可以很容易把一些功能进行梳理,达到最终目的功能集中化

模式结构

1)Visitor 抽象访问者角色:
为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它。

2)ConcreteVisitor具体访问者角色:
实现Visitor声明的接口。

3)Element抽象受访元素:
定义一个接受访问操作(accept()),它以一个访问者(Visitor)作为参数。

4)ConcreteElement 具体受访元素:
实现了抽象元素(Element)所定义的接受操作接口。

5)ObjectStructure 结构对象角色:
这是使用访问者模式必备的角色。它具备以下特性:能枚举它的元素;可以提供一个高层接口以允许访问者访问它的元素;如有需要,可以设计成一个复合对象或者一个聚集(如一个列表或无序集合)。

Demo

抽象访问者角色:

public interface IVisitor {
 public void accept(Feman feman);

 public void accept(Man man);
}

具体访问角色:

public class Visitor implements IVisitor {
 public void accept(Feman feman) {
  System.out.println(feman.getSex() + ":执行相关操作");
 }

 public void accept(Man man) {
  System.out.println(man.getSex() + ":执行相关操作");
 }
}

(注)Visitor中设置了同样的名称的方法且方法传参为实现同一接口的不同对象,即受访者元素。

抽象受访元素:

public abstract class Person {
 private String sex;
 public String getSex() {
  return sex;
 }
 public void setSex(String sex) {
  this.sex = sex;
 }
 public void accept(Visitor visitor) {
 };
}

具体受访元素:

public class Man extends Person {
 public Man() {
  this.setSex("男");
 }

 @Override
 public void accept(Visitor visitor) {
  visitor.accept(this);
 }
}
public class Feman extends Person {
 public Feman() {
  this.setSex("女");
 }

 @Override
 public void accept(Visitor visitor){
  visitor.accept(this);
 }
}

结构对象角色:

public class ObjectStruture {
 public static List<person> getList() {
  List<person> list = new ArrayList<person>();
  list.add(new Man());
  list.add(new Feman());
  list.add(new Feman());
  return list;
 }
}

执行过程:

Visitor visitor = new Visitor();
List<person> list = ObjectStruture.getList();
for (Person e : list) {
 e.accept(visitor);
}

执行结果:

男:执行相关操作
女:执行相关操作
女:执行相关操作

下面是一个完整的代码示例:

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

总结

以上就是本文关于Java设计模式之访问者模式使用场景及代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:Java编程—在测试中考虑多态、Java实现微信公众平台朋友圈分享功能详细代码、Java编程BigDecimal用法实例分享等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持。

时间: 2017-11-01

详解Java设计模式编程中的访问者模式

定义:封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作. 类型:行为类模式 类图: 例子: 例如,思考一下添加不同类型商品的购物车,当点击结算的时候,它计算出所有不同商品需付的费用.现在,计算逻辑即为计算这些不同类型商品的价格.或者说通过访问者模式我们把此逻辑转移到了另外一个类上面.让我们实现这个访问者模式的例子. 为了实现访问者模式,最先需要做的是创建能够被添加到购物车中代表不同类型商品(itemElement)的类. ItemElement

JAVA设计模式之访问者模式原理与用法详解

本文实例讲述了JAVA设计模式之访问者模式.分享给大家供大家参考,具体如下: 访问者模式: 一个作用于某对象结构中各元素的操作,使你可以在不改变各元素类数据结构的前提下增加作用于这些元素的新操作. 结构对象是访问者模式必备条件,且这个结构对象必须存在遍历自身各个对象的方法. 适用于:数据结构相对稳定,把数据结构和作用与其上的其它操作解耦,使得操作相对自由. 优点: 1.符合单一职责原则 2.扩展性良好:元素类可以通过接受不同的访问者来实现对不同操作的扩展. 缺点: 1.如果要增加新元素,则会让操

举例讲解设计模式中的访问者模式在Java编程中的运用

访问者(Visitor)模式:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作.访问者模式的结构图如下: 通过上图可以看到他有如下角色: 抽象访问者(Visitor)角色:定义接口,声明一个或多个访问操作. 具体访问者(ConcreteVisitor)角色:实现抽象访问者所声明的接口,也就是抽象访问者所声明的各个访问操作. 抽象元素(Visitable)角色:声明一个接受操作,接受一个访问者对象作为一个参数. 具体元素结点(Concret

JAVA设计模式之访问者模式详解

在阎宏博士的<JAVA与模式>一书中开头是这样描述访问者(Visitor)模式的: 访问者模式是对象的行为模式.访问者模式的目的是封装一些施加于某种数据结构元素之上的操作.一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变. 分派的概念 变量被声明时的类型叫做变量的静态类型(Static Type),有些人又把静态类型叫做明显类型(Apparent Type):而变量所引用的对象的真实类型又叫做变量的实际类型(Actual Type).比如: 复制代码 代码如下: List lis

Android编程设计模式之访问者模式详解

本文实例讲述了Android编程设计模式之访问者模式.分享给大家供大家参考,具体如下: 一.介绍 访问者模式是一种将数据操作与数据结构分离的设计模式,它是<设计模式>中23种设计模式中最复杂的一个,但它的使用频率并不高,正如<设计模式>的作者GOF对访问者模式的描述:大多数情况下,你不需要使用访问者模式,但是当你一旦需要使用它时,那你就是真的需要它了. 访问者模式的基本想法是,软件系统中拥有一个由许多对象构成的.比较稳定的对象结构,这些对象的类都拥有一个accept方法用来接受访问

JAVA设计模式之解释器模式详解

在阎宏博士的<JAVA与模式>一书中开头是这样描述解释器(Interpreter)模式的: 解释器模式是类的行为模式.给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器.客户端可以使用这个解释器来解释这个语言中的句子. 解释器模式的结构 下面就以一个示意性的系统为例,讨论解释器模式的结构.系统的结构图如下所示: 模式所涉及的角色如下所示: (1)抽象表达式(Expression)角色:声明一个所有的具体表达式角色都需要实现的抽象接口.这个接口主要是一个interpre

Java设计模式之策略模式详解

本文实例为大家分享了Java策略模式,供大家参考,具体内容如下 1.策略模式(Strategy Pattern)是一种比较简单的模式,也叫做政策模式(PolicyPattern). 定义如下: Define a family of algorithms,encapsulate each one,and make them interchangeable.    (定义一组算法,将每个算法都封装起来,并且使它们之间可以互换.) 策略模式的通用类图如下所示: 策略模式的三个角色: ● Context

java设计模式之模板方法模式详解

一.什么是模板方法模式 概念:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 通俗的讲,模板方法模式是通过把不变行为搬到超类,去除子类里面的重复代码提现它的优势,它提供了一个很好的代码复用平台.当不可变和可变的方法在子类中混合在一起的时候,不变的方法就会在子类中多次出现,这样如果摸个方法需要修改则需要修改很多个,虽然这个这个问题在设计之初就应该想好.这个时候模板方法模式就起到了作用了,通过模板方法模式把这些重复出现的

java 设计模式之适配器模式的详解

java 设计模式之适配器模式的详解 前言: 适配器模式(Adapter Pattern)又叫做变压器模式,也叫做包装模式.包装模式还包括装饰模式. 在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的. 一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中. UML类图:  具体代码: public class Client { public static void main(String[] args)

Java中的代理模式详解及实例代码

java 代理模式详解 前言: 在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为"代理"的第三者来实现间接引用.代理对象可以在客户端和目标对象之间起到 中介的作用,并且可以通过代理对象去掉客户不能看到 的内容和服务或者添加客户需要的额外服务. 简单来说代理模式就是通过一个代理对象去访问一个实际对象,并且可以像装饰模式一样给对象添加一些功能. 静态代理 所谓静态代理即在程序运行前代理类就已经存在,也就是说我们编写代码的时候就已经把代理类的代码写好了,而动态代理则

java设计模式之单例模式的详解及优点

java设计模式之单例模式 定义:如果一个类始终只能创建一个实例,那么这个类被称为单例类,这种设计模式被称为单例模式. Spring框架里面可以将所有生成的bean对象都设置为单例模式,只需要在配置Bean实例时指定scope="singleton"即可,或者不做配置默认即为单例模式. 我们可以创建一个小的Demo来演示单例模式的实现,只需要保证该类只能创建一个实例,我们可以用权限修饰符private修饰该类的构造器. 提供一个创建该类的接口,该接口只能用static修饰,类里面创建一