当前位置: 首页 > news >正文

小谈设计模式(29)—访问者模式

小谈设计模式(29)—访问者模式

  • 专栏介绍
    • 专栏地址
    • 专栏介绍
  • 访问者模式
    • 角色分析
      • 访问者
      • 被访问者
    • 优缺点分析
      • 优点
        • 将数据结构与算法分离
        • 增加新的操作很容易
        • 增加新的数据结构很困难
        • 4
      • 缺点
        • 增加新的数据结构比较困难
        • 增加新的操作会导致访问者类的数量增加
        • 3
        • 4
      • 总结
    • Java程序示例
      • 要求:
      • 首先,我们定义一个抽象的图形类(Element),其中包含一个接受访问者的方法 accept(),以及一个抽象的计算面积和周长的方法 calculate()。
      • 接下来,我们定义一个访问者接口(Visitor),其中包含了访问圆形和矩形的方法 visit()。
      • 然后,我们实现具体的访问者类(AreaVisitor和PerimeterVisitor),分别用于计算图形的面积和周长。
      • 最后,我们可以在客户端代码中使用访问者模式来计算图形的面积和周长。
      • 程序分析
    • 总结

专栏介绍

专栏地址

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);}
}

程序分析

在上面的代码中,我们创建了一个包含圆形和矩形的列表,并分别使用面积访问者和周长访问者来计算每个图形的面积和周长。

在这里插入图片描述

总结

访问者模式可以帮助我们将算法与对象结构分离开来,提高代码的可维护性和可扩展性。在实现访问者模式时,需要定义一个抽象的被访问者类和访问者接口,然后实现具体的被访问者类和访问者类。在客户端代码中,可以使用访问者来访问被访问者,并对其进行操作。

http://www.lryc.cn/news/194822.html

相关文章:

  • 【25】c++设计模式——>责任链模式
  • GlobalTransactional
  • Android Studio运行kotlin项目,一直Read timed out
  • Excel 的单元格内容和单元格格式
  • 4大软件测试策略的特点和区别(单元测试、集成测试、确认测试和系统测试)
  • armbian 安装mysql
  • Ubuntu22常用软件
  • 【CFD小工坊】浅水模型的边界条件
  • 电力物联网关智能通讯管理机-安科瑞黄安南
  • 用Flask构建一个AI翻译服务
  • 微信小程序引入阿里巴巴iconfont图标并使用
  • mysql面试题49:MySQL中不同text数据类型的最大长度
  • 从虚拟电厂在上海的实践探索看企业微电网数字化的意义
  • 创建并初始化线程池
  • 【LeetCode热题100】--136.只出现一次的数字
  • Java idea查看自定义注解的调用地方
  • ReLU激活函数
  • 【Android】adjustViewBounds 的理解和使用
  • Redis知识补充
  • IIS 部署.NetCore,最细步骤
  • 4.查询用户的累计消费金额及VIP等级
  • 解决MySQL错误-this is incompatible with sql_mode=only_full_group_by
  • UDP通信-广播、组播
  • 10-bean创建流程1一finishBeanFactoryInitialization(ConfigurableListableBeanFactory
  • 专题三:穷举、暴搜、深搜、回溯、剪枝【递归、搜索、回溯】
  • 国科云SSL证书讲堂:SSL证书安装常见问题盘点
  • Python3无法调用Sqlalchemy解决(mysqldb)
  • 2023/10/15总结
  • 关于图像分割SDK的一些基础认识
  • SpringMVC之国际化上传下载