专栏介绍
专栏地址
http://t.csdnimg.cn/VpriY
专栏介绍
主要对目前市面上常见的23种设计模式进行逐一分析和总结,希望有兴趣的小伙伴们可以看一下,会持续更新的。希望各位可以监督我,我们一起学习进步,加油,各位
访问者模式
访问者模式是一种行为型设计模式,它允许你将算法与一个对象结构分离开来。通过这种方式,可以在不改变对象结构的情况下,向对象结构中添加新的操作。
角色分析
访问者(Visitor)和被访问者(Element)
访问者
定义了一组可以访问不同类型被访问者的方法
被访问者
定义了接受访问者的方法。访问者通过被访问者的接口访问被访问者,并对其进行操作。
优缺点分析
优点
将数据结构与算法分离
访问者模式可以将数据结构与算法分离,使得算法可以独立于数据结构而变化,提高了代码的可维护性和可扩展性。
增加新的操作很容易
当需要增加新的操作时,只需要增加一个新的访问者类即可,不需要修改原有的代码。
增加新的数据结构很困难
当需要增加新的数据结构时,需要修改所有的访问者类,因此增加新的数据结构比较困难。
4
访问者模式符合单一职责原则和开闭原则
缺点
增加新的数据结构比较困难
当需要增加新的数据结构时,需要修改所有的访问者类,因此增加新的数据结构比较困难。
增加新的操作会导致访问者类的数量增加
当需要增加新的操作时,需要增加一个新的访问者类,因此访问者类的数量会增加。
3
导致系统变得复杂,增加了代码的阅读难度。
4
访问者模式需要对数据结构进行抽象,增加了系统的抽象性和理解难度。
总结
访问者模式适用于数据结构相对稳定,但是经常需要增加新的操作的场景,同时访问者模式也需要权衡系统的复杂度和可维护性。
Java程序示例
要求:
为一个图形库添加一个新的功能,即计算图形的面积和周长。我们可以使用访问者模式来实现这个功能。
首先,我们定义一个抽象的图形类(Element),其中包含一个接受访问者的方法 accept(),以及一个抽象的计算面积和周长的方法 calculate()。
abstract class Shape { public abstract void accept(Visitor visitor); public abstract void calculate(); }``` ### 然后,我们定义两个具体的图形类,圆形和矩形,它们都继承自图形类。 ```java class Circle extends 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 void calculate() { System.out.println("Calculating area and perimeter of circle"); } } class Rectangle extends 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 void calculate() { System.out.println("Calculating area and perimeter of rectangle"); } }
接下来,我们定义一个访问者接口(Visitor),其中包含了访问圆形和矩形的方法 visit()。
interface Visitor { void visit(Circle circle); void visit(Rectangle rectangle); }
然后,我们实现具体的访问者类(AreaVisitor和PerimeterVisitor),分别用于计算图形的面积和周长。
class AreaVisitor implements Visitor { public void visit(Circle circle) { double area = Math.PI * circle.getRadius() * circle.getRadius(); System.out.println("Area of circle: " + area); } public void visit(Rectangle rectangle) { double area = rectangle.getWidth() * rectangle.getHeight(); System.out.println("Area of rectangle: " + area); } } class PerimeterVisitor implements Visitor { public void visit(Circle circle) { double perimeter = 2 * Math.PI * circle.getRadius(); System.out.println("Perimeter of circle: " + perimeter); } public void visit(Rectangle rectangle) { double perimeter = 2 * (rectangle.getWidth() + rectangle.getHeight()); System.out.println("Perimeter of rectangle: " + perimeter); } }
最后,我们可以在客户端代码中使用访问者模式来计算图形的面积和周长。
public static void main(String[] args) { List<Shape> shapes = new ArrayList<>(); shapes.add(new Circle(5)); shapes.add(new Rectangle(3, 4)); Visitor areaVisitor = new AreaVisitor(); Visitor perimeterVisitor = new PerimeterVisitor(); for (Shape shape : shapes) { shape.accept(areaVisitor); shape.accept(perimeterVisitor); } }
程序分析
在上面的代码中,我们创建了一个包含圆形和矩形的列表,并分别使用面积访问者和周长访问者来计算每个图形的面积和周长。
总结
访问者模式可以帮助我们将算法与对象结构分离开来,提高代码的可维护性和可扩展性。在实现访问者模式时,需要定义一个抽象的被访问者类和访问者接口,然后实现具体的被访问者类和访问者类。在客户端代码中,可以使用访问者来访问被访问者,并对其进行操作。