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

软件设计模式之访问者模式(Visitor Pattern)

访问者模式是一种行为型设计模式,它允许你定义一系列操作,这些操作可以应用于对象结构中的元素,而不改变这些元素的类。通过这种方式,可以在不改变各个元素的类的情况下,增加新的操作。

1. 何时使用访问者模式?

  • 当需要对一个复杂对象结构中的各个元素进行不同的操作时。
  • 当对象结构中的类很少发生变化,但经常需要在这些类上定义新的操作时。
  • 当需要对对象结构中的元素进行多种不同的处理,并且这些处理需要分散在多个类中时。

2. 访问者模式的结构

访问者模式主要包含以下角色:

  • Visitor(访问者):定义了对对象结构中各个元素的操作,可以通过该接口实现不同的访问者来执行不同的操作。
  • ConcreteVisitor(具体访问者):实现了 Visitor 接口,定义了具体的操作逻辑。
  • Element(元素):定义了一个接受访问者的方法,通常是一个抽象类或接口,可以包含多个不同的具体子类。
  • ConcreteElement(具体元素):实现了 Element 接口,提供了 accept 方法的具体实现。
  • ObjectStructure(对象结构):包含了一个元素的集合,并提供了遍历这些元素的方法。

3. Java 代码示例

让我们通过一个简单的示例来说明访问者模式的用法。假设我们有一个图形类的对象结构,其中包含了不同类型的图形,如圆形和矩形。我们需要对这些图形进行不同的操作,如计算面积和周长。

// 定义访问者接口
interface Visitor {void visit(Circle circle);void visit(Rectangle rectangle);
}// 具体访问者:计算面积和周长
class AreaCalculator implements Visitor {double totalArea = 0;double totalPerimeter = 0;@Overridepublic void visit(Circle circle) {totalArea += Math.PI * circle.getRadius() * circle.getRadius();totalPerimeter += 2 * Math.PI * circle.getRadius();}@Overridepublic void visit(Rectangle rectangle) {totalArea += rectangle.getWidth() * rectangle.getHeight();totalPerimeter += 2 * (rectangle.getWidth() + rectangle.getHeight());}
}// 元素接口
interface Element {void accept(Visitor visitor);
}// 具体元素:圆形
class Circle implements Element {private double radius;public Circle(double radius) {this.radius = radius;}public double getRadius() {return radius;}@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}
}// 具体元素:矩形
class Rectangle implements Element {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;}@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}
}// 对象结构
class ObjectStructure {private List<Element> elements = new ArrayList<>();public void addElement(Element element) {elements.add(element);}public void removeElement(Element element) {elements.remove(element);}public void accept(Visitor visitor) {for (Element element : elements) {element.accept(visitor);}}
}// 示例代码
public class Main {public static void main(String[] args) {ObjectStructure objectStructure = new ObjectStructure();objectStructure.addElement(new Circle(5));objectStructure.addElement(new Rectangle(3, 4));AreaCalculator areaCalculator = new AreaCalculator();objectStructure.accept(areaCalculator);System.out.println("Total Area: " + areaCalculator.totalArea);System.out.println("Total Perimeter: " + areaCalculator.totalPerimeter);}
}

在上面的示例中,我们定义了访问者接口 Visitor,并实现了具体的访问者 AreaCalculator,用于计算图形的面积和周长。同时,我们定义了元素接口 Element 和具体元素 Circle 和 Rectangle,并在其中实现了接受访问者的方法。最后,我们定义了对象结构 ObjectStructure,用于存储元素,并提供了接受访问者的方法。通过这样的设计,我们可以轻松地对图形进行不同的操作,而无需修改图形类的代码。

通过以上介绍,希望你对访问者模式有了更深入的了解,并能在实际项目中灵活应用。

相关文章:

  • redis-RedisTemplate.opsForGeo 的geo地理位置及实现附近的人的功能
  • 学会玩游戏,智能究竟从何而来?
  • HarmonyOS开发云工程与开发云函数
  • 加密与安全_探索常用编码算法
  • Vue官网“食用指南”
  • Appium手机Android自动化
  • 数据结构·顺序表实现通讯录
  • 92. 递归实现指数型枚举 刷题笔记
  • LeetCode 热题 100 | 图论(上)
  • spring boot整合cache使用memcached
  • uniapp+node.js前后端做帖子模块:获取帖子列表(社区管理平台的小程序)
  • 本科毕业设计:计及并网依赖性的分布式能源系统优化研究。(C语言实现)(内包含NSGA II优化算法)(一)
  • Mint_21.3 drawing-area和goocanvas的FB笔记(一)
  • Rust调用同级目录中的rs文件和调用下级目录中的rs文件
  • JAVA泛型浅析
  • 【Amaple教程】5. 插件
  • 【附node操作实例】redis简明入门系列—字符串类型
  • ES6语法详解(一)
  • extract-text-webpack-plugin用法
  • Java 内存分配及垃圾回收机制初探
  • Java编程基础24——递归练习
  • js作用域和this的理解
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • oldjun 检测网站的经验
  • Python_OOP
  • vue-router的history模式发布配置
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 聊聊flink的TableFactory
  • 算法-插入排序
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 译自由幺半群
  • 带你开发类似Pokemon Go的AR游戏
  • 进程与线程(三)——进程/线程间通信
  • ​软考-高级-系统架构设计师教程(清华第2版)【第15章 面向服务架构设计理论与实践(P527~554)-思维导图】​
  • # 安徽锐锋科技IDMS系统简介
  • (SpringBoot)第七章:SpringBoot日志文件
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • (转)es进行聚合操作时提示Fielddata is disabled on text fields by default
  • (转)setTimeout 和 setInterval 的区别
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .net 按比例显示图片的缩略图
  • .Net 应用中使用dot trace进行性能诊断
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • @Responsebody与@RequestBody
  • @拔赤:Web前端开发十日谈
  • [100天算法】-实现 strStr()(day 52)
  • [BZOJ3757] 苹果树
  • [BZOJ4010]菜肴制作
  • [IDF]啥?
  • [leetcode]Symmetric Tree
  • [Mvc]在ASP.NET MVC中使用Repeater