设计模式二十四-访问者模式

访问者模式允许在不修改对象结构的情况下定义新的操作。它通过元素类的accept方法接受访问者,访问者中的visit方法执行特定操作。适用于添加新操作而不改变对象结构的场景。文章提供了一个图形库的Java示例,展示了如何使用访问者模式计算图形的面积和周长。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

访问者模式是一种行为型设计模式,它允许我们在不修改对象结构的情况下定义新的操作。在访问者模式中,我们通过定义一个访问者类和一组元素类来实现这个模式。访问者类中定义了一组 visit() 方法,这些方法用于执行特定的操作,而元素类中则提供了一个 accept() 方法,这个方法用于接受访问者并调用它的 visit() 方法。

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

  1. 当我们需要定义一个新的操作,但不想修改现有的对象结构时,可以使用访问者模式。

  2. 当我们需要对一个对象结构中的元素进行复杂的操作,而且这些操作的具体实现可能不同,也可以使用访问者模式。

  3. 当我们需要对一个对象结构中的元素进行多种不同的操作,并且这些操作的组合方式可能不同,同样可以使用访问者模式。

原理: 访问者模式的核心思想是:将算法与数据结构分离。在访问者模式中,我们将算法封装到一个访问者类中,而将数据结构封装到一个元素类中。元素类中提供了一个 accept() 方法,这个方法用于接受访问者,并将自己传递给访问者。访问者类中定义了一组 visit() 方法,每个 visit() 方法用于执行特定的操作。在访问者模式中,我们可以根据需要定义多个访问者类和多个元素类,从而实现不同的算法和数据结构组合。

Java实例: 以下是一个使用访问者模式的Java示例,假设我们要实现一个图形库,其中包含多种不同的图形元素,例如圆形、矩形和三角形等。我们需要对这些图形元素进行多种不同的操作,例如计算面积、计算周长和绘制图形等。我们可以使用访问者模式来实现这个功能:

// 元素类接口
public interface Shape {
    void accept(Visitor visitor);
}

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

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

    public double getRadius() {
        return radius;
    }

    public void accept(Visitor 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;
    }

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

// 具体访问者类:计算面积访问者
public class AreaCalculator implements Visitor {
    private double area;
    public void visit(Circle circle) {
    area += Math.PI * circle.getRadius() * circle.getRadius();
    }

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

    public double getArea() {
        return area;
    }
}
// 具体访问者类:计算周长访问者
public class PerimeterCalculator implements Visitor {
    private double perimeter;
    public void visit(Circle circle) {
        perimeter += 2 * Math.PI * circle.getRadius();
    }

    public void visit(Rectangle rectangle) {
        perimeter += 2 * (rectangle.getWidth() + rectangle.getHeight());
    }

    public double getPerimeter() {
        return perimeter;
    }
}
// 访问者接口
public interface Visitor {
    void visit(Circle circle);
    void visit(Rectangle rectangle);
}
// 测试代码
public class Client {
    public static void main(String[] args) {
        List<Shape> shapes = new ArrayList<>();
        shapes.add(new Circle(3));
        shapes.add(new Rectangle(4, 5));
        shapes.add(new Circle(5));
        // 计算所有图形的面积
        AreaCalculator areaCalculator = new AreaCalculator();
        for (Shape shape : shapes) {
            shape.accept(areaCalculator);
        }
        System.out.println("Total area: " + areaCalculator.getArea());

        // 计算所有图形的周长
        PerimeterCalculator perimeterCalculator = new PerimeterCalculator();
        for (Shape shape : shapes) {
            shape.accept(perimeterCalculator);
        }
        System.out.println("Total perimeter: " + perimeterCalculator.getPerimeter());
    }
}


在这个示例中,我们定义了一个元素类接口 Shape,以及两个具体元素类 Circle 和 Rectangle。我们还定义了一个访问者接口 Visitor,以及两个具体访问者类 AreaCalculator 和 PerimeterCalculator。在测试代码中,我们创建了多个不同的图形元素,然后使用访问者模式分别计算了它们的面积和周长。

总之,访问者模式是一种非常有用的设计模式,它可以帮助我们在不修改对象结构的情况下定义新的操作。在实际的项目中,我们可以使用访问者模式来实现复杂的算法,同时又保持代码的清晰和易于维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沉墨的夜

您的鼓励将是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值