Java学设计模式之访问者模式
一、访问者模式概念
1.1 什么是访问者模式
访问者模式是一种行为型设计模式,它允许你在不改变元素类的前提下定义新操作。这意味着你可以将算法与对象结构分离开来。
结构
-
访问者(Visitor): 定义了对于每个元素对象的操作,可以是具体的操作或者算法。
-
具体访问者(Concrete Visitor): 实现了访问者接口中定义的各种操作,确定了每个具体元素对象被访问时所执行的具体行为。
-
元素(Element): 定义了接受访问者对象的接口,通常包含一个
accept
方法,它接收访问者作为参数。 -
具体元素(Concrete Element): 实现了元素接口,并实现了
accept
方法,用于将自身传递给访问者对象。 -
对象结构(Object Structure): 维护了一个元素的集合,并提供了迭代器或者类似的方法,以便让访问者对象能够访问它的元素。
二、访问者模式代码
2.1 访问者接口
public interface ShapeVisitor {
void visit(Circle circle);
void visit(Rectangle rectangle);
}
2.2 具体访问者
public class AreaCalculator implements ShapeVisitor {
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;
}
}
2.3 元素接口
public interface Shape {
void accept(ShapeVisitor visitor);
}
2.4 具体元素
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.visit(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.visit(this);
}
}
2.5 对象结构
public class Drawing {
private List<Shape> shapes = new ArrayList<>();
public void addShape(Shape shape) {
shapes.add(shape);
}
public void accept(ShapeVisitor visitor) {
for (Shape shape : shapes) {
shape.accept(visitor);
}
}
}
2.6 客户端
public class VisitorPatternTest {
public static void main(String[] args) {
Drawing drawing = new Drawing();
drawing.addShape(new Circle(5));
drawing.addShape(new Rectangle(3, 4));
AreaCalculator areaCalculator = new AreaCalculator();
drawing.accept(areaCalculator);
System.out.println("总面积:" + areaCalculator.getTotalArea());
// 输出:
// 总面积:90.53981633974483
}
}
三、总结
访问者模式通过将操作与元素对象分离开来,使得你可以定义新的操作而无需修改元素类。这提高了代码的可扩展性,并使得操作可以轻松地在不同的元素对象上执行。但是,访问者模式也会增加代码的复杂度,因为它引入了额外的接口和类。因此,在使用访问者模式时需要权衡其优缺点。