Java访问者模式实现优雅的对象结构处理

 更新时间:2023年04月22日 11:20:15   作者:.番茄炒蛋  
Java访问者模式是一种行为型设计模式,它通过将数据结构和数据操作分离,实现对复杂对象结构的处理。它将数据结构中的每个元素都转换为访问者能够识别的形式,从而使得数据操作可以在不影响数据结构的前提下进行扩展和变化

介绍

Java访问者模式(Visitor Pattern)是一种行为型设计模式,它允许将算法与其所操作的对象分离.该模式定义了一个访问者对象,它可以访问不同类型的对象并执行一些操作,同时也能让你在不修改现有代码的情况下,添加新的操作.

再访问者模式中,有两个重要的角色:访问者和元素. 元素是一个对象结构的组成部分.访问者是一个表示要执行的操作的对象.访问者可以通过元素的接受方法来访问元素.

Java访问者模式通常涉及以下5种角色:

  • 抽象访问者(Visitor):定义了可以访问每个元素的访问方法.
  • 具体访问者(Concrete Visitor):实现了抽象访问者定义的访问方法,包含针对不同元素的具体操作.
  • 抽象元素(Element):定义了一个接受访问者对象的方法,使访问者可以访问自己.
  • 具体元素(Concrete Element):实现了抽象元素定义的接受访问者方法,使访问者能够访问自己.
  • 对象结构(Object Structure):包含元素的集合,可以提供迭代器遍历元素,并且可以接受访问者的访问.

实现

动物园中有不同种类的动物,包括狗,猫和鸟.访问者模式可以用于统计不同类型的动物的个数,以及不同类型的动物的属性信息.

抽象元素

public interface Animal {
    void accept(Visitor visitor);
}

具体元素

@Data
public class Bird implements Animal{
    private String name;
    private String habitat;
    public Bird(String name, String habitat) {
        this.name = name;
        this.habitat = habitat;
    }
    @Override
    public void accept(Visitor visitor) {
        visitor.visitor(this);
    }
}
@Data
public class Cat implements Animal{
    private String sound;
    private int age;
    public Cat(String sound, int age) {
        this.sound = sound;
        this.age = age;
    }
    @Override
    public void accept(Visitor visitor) {
        visitor.visitor(this);
    }
}
@Data
public class Dog implements Animal{
    private String color;
    private int size;
    public Dog(String color, int size) {
        this.color = color;
        this.size = size;
    }
    @Override
    public void accept(Visitor visitor) {
        visitor.visitor(this);
    }
}

抽象访问者

public interface Visitor {
    void visitor(Dog dog);
    void visitor(Cat cat);
    void visitor(Bird bird);
}

具体访问者

public class AnimalCountVisitor implements Visitor{
    private int dogCount;
    private int birdCount;
    private int catCount;
    @Override
    public void visitor(Dog dog) {
        dogCount++;
    }
    @Override
    public void visitor(Cat cat) {
        catCount++;
    }
    @Override
    public void visitor(Bird bird) {
        birdCount++;
    }
    public void printCount(){
        System.out.println("狗的个数:"+dogCount);
        System.out.println("猫的个数:"+catCount);
        System.out.println("鸟的个数:"+birdCount);
    }
}
public class AnimalFeatureVisitor implements Visitor {
    private List<String> features;
    public AnimalFeatureVisitor() {
        features = new ArrayList<>();
    }
    @Override
    public void visitor(Dog dog) {
        features.add("Dog:color=" + dog.getColor() + ",size=" + dog.getSize());
    }
    @Override
    public void visitor(Cat cat) {
        features.add("Car:sound=" + cat.getSound() + ",age=" + cat.getAge());
    }
    @Override
    public void visitor(Bird bird) {
        features.add("Bird:name=" + bird.getName() + ",habitat=" + bird.getHabitat());
    }
    public void printFeatures(){
        features.forEach(System.out::println);
    }
}

测试

public class Demo {
    public static void main(String[] args) {
        List<Animal> animals = new ArrayList<>();
        animals.add(new Dog("褐色", 50));
        animals.add(new Dog("白色", 45));
        animals.add(new Cat("喵喵叫", 2));
        animals.add(new Cat("呜呜声", 3));
        animals.add(new Bird("鹦鹉", "森林"));
        animals.add(new Bird("麻雀", "田野"));
        AnimalCountVisitor animalCountVisitor = new AnimalCountVisitor();
        AnimalFeatureVisitor animalFeatureVisitor = new AnimalFeatureVisitor();
        animals.forEach(animal -> {
            animal.accept(animalCountVisitor);
            animal.accept(animalFeatureVisitor);
        });
        animalCountVisitor.printCount();
        animalFeatureVisitor.printFeatures();
    }
}

再这个例子中,我们定义了三种动物类,包括Dog,Cat和Bird,它们都实现了Animal接口,并且是心啊了accept方法,其中传入了Visitor类型的参数.

接下来,定义了Visitor接口,其中包含了visitor方法,该方法根据传入的不同类型的动物进行访问.

再具体的Visitor的实现中,定义了AnimalCountVisitor和AnimalFeatureVisitor两个访问者,前者用于统计不同类型的动物的个数,后者用于打印不同类型的动物的属性.

总结

优点

  • 分离算法与对象:访问者模式使得算法与对象分离成为可能,因为算法被定义在访问者中,而对象则在被访问时向访问者公开自己的数据.
  • 扩展性好:该模式可以方便地添加新的操作而不会影响现有的对象结构,因为访问者模式将对象结构与操作分离开来.
  • 符合开闭原则:访问者模式符合开闭原则,因为您可以在不更改现有代码的情况下添加新的访问者和新的元素类型.
  • 简化代码逻辑:访问者模式将对象和操作分离开来,简化了代码逻辑.

缺点

  • 增加新的元素类型困难:当需要增加新的元素类型时,必须修改现有的访问者接口,这可能导致对现有代码的修改.
  • 破坏封装:访问者模式需要将对象的内部数据暴漏给访问者,这可能破坏对象的封装性.

应用场景

  • 当需要对一个复杂对象结构进行操作而不想暴漏其内部实现时,可以使用访问者模式.
  • 当需要为对象结构中的各个对象增加一些新的操作而不影响其类层次结构时,可以使用访问者模式.
  • 当对象的类层次结构发生变化,但其操作仍然保持相对稳定时,可以使用访问者模式.
  • 当需要在运行时动态确定要执行的操作时,可以使用访问者模式.

到此这篇关于Java访问者模式实现优雅的对象结构处理的文章就介绍到这了,更多相关Java访问者模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Boot Admin 监控指标接入Grafana可视化的实例详解

    Spring Boot Admin 监控指标接入Grafana可视化的实例详解

    Spring Boot Admin2 自带有部分监控图表,如图,有线程、内存Heap和内存Non Heap,这篇文章主要介绍了Spring Boot Admin 监控指标接入Grafana可视化,需要的朋友可以参考下
    2022-11-11
  • spring与mybatis三种整合方法

    spring与mybatis三种整合方法

    这篇文章主要介绍了spring与mybatis三种整合方法,需要的朋友可以参考下
    2017-04-04
  • Hadoop源码分析四远程debug调试

    Hadoop源码分析四远程debug调试

    本篇是Hadoop源码分析系列文章第四篇,主要介绍一下Hadoop的远程debug调试步骤,后续本系列文章会持续更新,有需要的朋友可以借鉴参考下
    2021-09-09
  • Java异常处理之try...catch...finally详解

    Java异常处理之try...catch...finally详解

    今天小编就为大家分享一篇关于Java异常处理之try...catch...finally详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Java面试题冲刺第二十八天--数据库(5)

    Java面试题冲刺第二十八天--数据库(5)

    这篇文章主要为大家分享了最有价值的三道关于数据库的面试题,涵盖内容全面,包括数据结构和算法相关的题目、经典面试编程题等,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • 浅谈JavaIO之try with底层原理

    浅谈JavaIO之try with底层原理

    众所周知,所有被打开的系统资源,比如流、文件或者Socket连接等,都需要被开发者手动关闭,否则随着程序的不断运行,资源泄露将会累积成重大的生产事故。本文将介绍JavaIO之try with底层原理。
    2021-06-06
  • 详解springboot整合mongodb

    详解springboot整合mongodb

    本篇文章主要介绍了详解springboot整合mongodb,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • ssm整合之Spring整合MyBatis框架配置事务的详细教程

    ssm整合之Spring整合MyBatis框架配置事务的详细教程

    这篇文章主要介绍了ssm整合之Spring整合MyBatis框架配置事务,本文通过图文实例代码相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • 详解Java如何利用位操作符创建位掩码

    详解Java如何利用位操作符创建位掩码

    在本文中,我们来看看如何使用位操作符实现低级别的位掩码。我们将看到我们如何将一个单一的int变量作为一个单独的数据容器,感兴趣的可以跟随小编一起学习一下
    2022-10-10
  • IDEA 中创建Spring Data Jpa 项目的示例代码

    IDEA 中创建Spring Data Jpa 项目的示例代码

    这篇文章主要介绍了IDEA 中创建Spring Data Jpa 项目的示例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04

最新评论