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

作者:致良知,让良知的心伴你通行。 时间:2021-06-27 13:34:25 

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

来源:https://www.2cto.com/kf/201612/582504.html

标签:java,访问者模式
0
投稿

猜你喜欢

  • C#探秘系列(三)——StackTrace,Trim

    2022-04-27 21:24:03
  • C++编程中的函数指针初步解析

    2023-05-04 23:08:24
  • Android DataBinding布局的加载深入探究

    2023-02-26 08:45:52
  • C#生成漂亮验证码完整代码类

    2022-06-17 14:03:33
  • C#基础学习系列之Attribute和反射详解

    2022-07-19 17:55:40
  • Android仿支付宝手势密码解锁功能

    2023-02-14 09:06:46
  • java数据结构排序算法之树形选择排序详解

    2022-07-22 23:43:17
  • C#自定义鼠标拖拽Drag&Drop效果之基本原理及基本实现代码

    2021-06-09 14:09:24
  • C#中的委托和事件

    2021-09-14 01:01:55
  • Android编程之页面切换测试实例

    2022-04-03 22:13:11
  • Java基础知识精通二维数组的应用

    2022-02-03 03:01:28
  • SpringCloud学习笔记之Feign远程调用

    2023-08-15 09:57:01
  • Spring boot中@Conditional和spring boot的自动配置实例详解

    2023-06-20 09:36:14
  • java中response对象用法实例分析

    2023-08-23 18:51:04
  • 关于idea更新到2020.2.3无法创建web项目原因 library is not specified

    2022-11-24 10:13:28
  • Android实现多媒体录音笔

    2022-03-26 17:25:00
  • C#删除只读文件或文件夹(解决File.Delete无法删除文件)

    2022-06-30 15:01:59
  • Java 在PDF中添加条形码的两种方法

    2023-05-29 19:10:23
  • Android 区别真机和模拟器的几种方法

    2022-05-19 14:13:44
  • Java基础学习之集合底层原理

    2023-09-30 22:16:40
  • asp之家 软件编程 m.aspxhome.com