访问者模式

访问者模式(Visitor Pattern)是一种行为型设计模式,它允许你在不修改对象结构的情况下向对象集合中添加新的操作。这一模式通过将操作分离到单独的访问者类中来实现,这些访问者类包含了对各种对象类型进行操作的逻辑。

结构

Visitor接口‌

定义一个或多个访问操作,每个操作对应一个对象类型,这些操作是抽象的,具体的实现由具体的访问者类提供。

java 复制代码
package org.example.visitor;

public interface Visitor {
    void visit(Circle circle);
    void visit(Rectangle rectangle);
}

ConcreteVisitor‌ 类实现 Vistor 接口

实现Visitor接口中定义的操作,对每个具体对象类型执行特定的行为。

java 复制代码
package org.example.visitor;

public class AreaVisitor implements Visitor{
    private double totalArea = 0;

    @Override
    public void visit(Circle circle) {
        totalArea += Math.PI * circle.getRadius() * circle.getRadius();
    }

    @Override
    public void visit(Rectangle rectangle) {
        totalArea += rectangle.getWidth() * rectangle.getHeight();
    }

    public double getTotalArea() {
        return totalArea;
    }
}

‌Element接口‌

定义一个Accept操作,该操作接受一个访问者对象作为参数,Element接口是抽象的,具体的实现由具体的元素类提供。

java 复制代码
package org.example.visitor;

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

‌ConcreteElement‌ 类实现 Element 接口

实现Element接口中的Accept操作,当Accept操作被调用时,它调用访问者的相应方法,并将自身作为参数传递。

java 复制代码
package org.example.visitor;

public class Rectangle implements Element{
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    public double getWidth() {
        return width;
    }

    public double getHeight() {
        return height;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}
java 复制代码
package org.example.visitor;

public class Circle implements Element{
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

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

ObjectStructure‌

是一个包含元素集合的类,它可以迭代这些元素并接受访问者的访问,ObjectStructure可以是复合对象、集合、列表或其他任何包含多个元素的复杂结构。

java 复制代码
package org.example.visitor;

import java.util.ArrayList;
import java.util.List;

public class ObjectStructure {
    private List<Element> elements = new ArrayList<>();

    public void addElement(Element element) {
        elements.add(element);
    }

    public void accept(Visitor visitor) {
        for (Element element : elements) {
            element.accept(visitor);
        }
    }
}

测试

java 复制代码
package org.example.visitor;

public class VisitorMain {
    public static void main(String[] args) {
        ObjectStructure obj = new ObjectStructure();
        obj.addElement(new Circle(10));
        obj.addElement(new Rectangle(10, 20));

        AreaVisitor visitor = new AreaVisitor();
        obj.accept(visitor);

        System.out.println("Total area:" + visitor.getTotalArea());
    }
}

工作原理

  1. 客户端创建ObjectStructure实例,并填充它以包含需要操作的元素。
  2. 客户端创建一个或多个ConcreteVisitor实例,这些实例包含了对元素执行的具体操作。
  3. 客户端通过调用ObjectStructure的Accept方法,将ConcreteVisitor传递给元素集合。
  4. 每个元素调用其Accept方法,并接受ConcreteVisitor的访问。
  5. ConcreteVisitor对每个元素执行相应的操作(这些操作在ConcreteVisitor中定义)。

优点

  1. ‌增加新的操作容易‌:无需修改现有的类结构,只需增加新的ConcreteVisitor类即可。
  2. ‌符合开闭原则‌:可以在不修改现有代码的情况下扩展系统的功能。
  3. ‌操作与对象分离‌:操作被封装在访问者类中,与对象结构分离,提高了系统的灵活性和可维护性。
  4. ‌复杂对象结构上的操作‌:访问者模式使得对复杂对象结构(如树形结构、图形结构等)上的操作变得更加容易和直观。

缺点

  1. ‌增加新的元素类困难‌:每当增加新的元素类时,都需要在每个ConcreteVisitor类中增加相应的操作方法,这违反了开闭原则。
  2. ‌破坏封装性‌:访问者模式要求元素类公开其内部状态和结构给访问者,这可能会破坏对象的封装性。
  3. ‌具体元素对访问者公布细节‌:元素类需要知道访问者将对其执行哪些操作,这可能会导致元素类与访问者类之间的紧密耦合。
  4. ‌运行时开销‌:由于需要遍历整个对象结构并调用访问者的方法,访问者模式可能会带来一定的运行时开销。

应用场景

访问者模式适用于以下场景:

  1. ‌对象结构相对稳定‌:当对象结构(如树形结构、图形结构等)相对稳定,而需要对其中的元素进行多种不同的操作时。
  2. ‌操作易于变化‌:当系统中的操作经常需要变化或增加时,使用访问者模式可以避免频繁地修改对象结构。
  3. ‌跨多个类的操作‌:当需要对多个不同类的对象执行相同的操作时,可以使用访问者模式将这些操作封装在访问者类中。
  4. ‌累积与分离操作‌:当需要对对象结构中的元素进行累积(如求和、统计等)或分离(如过滤、分类等)操作时,访问者模式提供了一种优雅的实现方式。
相关推荐
WangMing_X7 天前
C# 23种设计模式(4)访问者模式(Visitor Pattern)
开发语言·设计模式·c#·访问者模式
我码玄黄10 天前
JS设计模式之访问者模式
javascript·设计模式·访问者模式
博风11 天前
设计模式:24、访问者模式
设计模式·访问者模式
喵手18 天前
设计模式探秘:迭代器模式与访问者模式详解
设计模式·迭代器模式·访问者模式
橘色的喵20 天前
C++编程:模拟实现CyberRT的DataVisitor和DataDispatcher
c++·访问者模式·观察者·cyberrt·datavisitor·datadispatcher
小白不太白9501 个月前
设计模式之 访问者模式
java·设计模式·访问者模式
萨达大1 个月前
23种设计模式-访问者(Visitor)设计模式
java·c++·设计模式·软考·访问者模式·软件设计师·行为型设计模式
丶白泽2 个月前
重修设计模式-行为型-访问者模式
java·设计模式·访问者模式·1024程序员节
努力找工作的OMArmy2 个月前
软件开发----设计模式每日刷题(转载于牛客)
java·单例模式·设计模式·策略模式·访问者模式·模板方法模式·开闭原则