引言
在软件开发过程中,我们经常会遇到需要对一组对象进行特定操作的情况。当我们需要在不改变对象的类结构的前提下,增加特定操作,访问者模式就可以派上用场。访问者模式将对象结构与操作分离,使得操作可以独立于对象的结构进行变化。
什么是访问者模式?
访问者模式是一种行为型设计模式,它允许你定义能在不同类对象上执行的操作,而无需改变这些类的结构。通过引入访问者,可以在不改变对象结构的情况下,为对象结构中的每个元素增加新操作。
模式结构
访问者模式包含以下几个角色:
- 访问者(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
总结
访问者模式能够在不改变对象的类结构的情况下,为对象定义新的操作。通过将操作封装在访问者中,并通过对象结构接口进行调用,我们可以轻松地增加新的操作,同时保持对象结构的稳定。访问者模式常用于解决对象结构中的元素操作问题,并且能够提高代码的可扩展性和复用性。
本文来自极简博客,作者:糖果女孩,转载请注明原文链接:Java中的访问者模式:在不改变类结构的情况下增加新操作