Java中的访问者模式:在不改变类结构的情况下增加新操作

糖果女孩 2019-12-08 ⋅ 26 阅读

引言

在软件开发过程中,我们经常会遇到需要对一组对象进行特定操作的情况。当我们需要在不改变对象的类结构的前提下,增加特定操作,访问者模式就可以派上用场。访问者模式将对象结构与操作分离,使得操作可以独立于对象的结构进行变化。

什么是访问者模式?

访问者模式是一种行为型设计模式,它允许你定义能在不同类对象上执行的操作,而无需改变这些类的结构。通过引入访问者,可以在不改变对象结构的情况下,为对象结构中的每个元素增加新操作。

模式结构

访问者模式包含以下几个角色:

  • 访问者(Visitor): 定义可访问对象结构中的每个元素的新操作。它可以通过对象结构中的元素角色调用具体元素的操作。
  • 具体访问者(ConcreteVisitor): 实现访问者接口,并实现新操作。
  • 元素(Element): 定义一个接受访问者操作的接口。
  • 具体元素(ConcreteElement): 实现元素接口,提供其接受具体访问者操作的实现。
  • 对象结构(Object Structure): 存储元素对象,并提供访问者访问元素的接口。

示例

假设有一个图形库,其中包含不同类型的图形对象(如圆形、矩形等)。我们想要在不改变图形类结构的情况下,为图形库添加一个新的操作-计算图形的面积。

首先,我们定义一个访问者接口和一个对象结构接口:

// 访问者接口
public interface ShapeVisitor {
    void visitCircle(Circle circle);
    void visitRectangle(Rectangle rectangle);
    void visitTriangle(Triangle triangle);
}

// 对象结构接口
public interface Shape {
    void accept(ShapeVisitor visitor);
}

接下来,我们实现具体元素类和具体访问者类:

// 具体元素类-圆形
public class Circle implements Shape {
    private double radius;

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

    public double getRadius() { return radius; }

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

// 具体元素类-矩形
public class Rectangle implements Shape {
    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(ShapeVisitor visitor) {
        visitor.visitRectangle(this);
    }
}

// 具体元素类-三角形
public class Triangle implements Shape {
    private double base;
    private double height;

    public Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }

    public double getBase() { return base; }
    public double getHeight() { return height; }

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

// 具体访问者类-面积计算访问者
public class AreaVisitor implements ShapeVisitor {
    @Override
    public void visitCircle(Circle circle) {
        double area = Math.PI * Math.pow(circle.getRadius(), 2);
        System.out.println("计算圆形的面积:" + area);
    }

    @Override
    public void visitRectangle(Rectangle rectangle) {
        double area = rectangle.getWidth() * rectangle.getHeight();
        System.out.println("计算矩形的面积:" + area);
    }

    @Override
    public void visitTriangle(Triangle triangle) {
        double area = 0.5 * triangle.getBase() * triangle.getHeight();
        System.out.println("计算三角形的面积:" + area);
    }
}

现在,我们可以通过访问者模式计算图形的面积,而无需改变图形类结构:

public class Main {
    public static void main(String[] args) {
        List<Shape> shapes = new ArrayList<>();
        shapes.add(new Circle(5));
        shapes.add(new Rectangle(6, 8));
        shapes.add(new Triangle(4, 7));

        ShapeVisitor areaVisitor = new AreaVisitor();
        for (Shape shape : shapes) {
            shape.accept(areaVisitor);
        }
    }
}

运行上述代码,将输出以下结果:

计算圆形的面积:78.53981633974483
计算矩形的面积:48.0
计算三角形的面积:14.0

总结

访问者模式能够在不改变对象的类结构的情况下,为对象定义新的操作。通过将操作封装在访问者中,并通过对象结构接口进行调用,我们可以轻松地增加新的操作,同时保持对象结构的稳定。访问者模式常用于解决对象结构中的元素操作问题,并且能够提高代码的可扩展性和复用性。


全部评论: 0

    我有话说: