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

news2024/11/19 10:33:25

小谈设计模式(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.coloradmin.cn/o/1095157.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

windows10系统-16-制作导航网站WebStack-Hugo

上个厕所功夫把AI导航搞定了 使用Hugo搭建静态站点 如何使用Hugo框架搭建一个快如闪电的静态网站 1 Hugo 参考Hugo中文文档 参考使用Hugo搭建个人网站 Hugo是由Go语言实现的静态网站生成器。简单、易用、高效、易扩展、快速部署。 1.1 安装Hugo 二进制安装&#xff08;推荐…

iMeta框架使用方法

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是「奇点」&#xff0c;江湖人称 singularity。刚工作几年&#xff0c;想和大家一同进步&#x1f91d;&#x1f91d; 一位上进心十足的【Java ToB端大厂…

判断一棵树是否为完全二叉树——层序遍历

完全二叉树&#xff08;包括满二叉树 &#xff09; 利用层序遍历&#xff0c;当取顶取到空的时候&#xff08;这个时候取的这一层的所有节点是一定在队列里面的&#xff09;&#xff0c;就结束入队&#xff0c;然后判断他的后面的节点是否都为空 这里重点还是要理解二叉树的层…

求二叉树的高度——函数递归的思想

二叉树的高度&#xff1a;左右两个数最高的那个的1 int TreeHight(BTNode* root) {if (root NULL){return 0;}int lefhightTreeHight(root->left);int righthight TreeHight(root->right);return lefhight > righthight ? TreeHight(root->left) 1 : TreeHight…

集合的进阶

不可变集合 创建不可变的集合 在创建了之后集合的长度内容都不可以变化 静态集合的创建在list &#xff0c;set &#xff0c;map接口当中都可以获取不可变集合 方法名称说明static list of(E …elements)创建一个具有指定元素集合list集合对象staticlist of(E…elements)创…

51系列—基于51单片机的RS232通信示例

一、目录 1、51单片机串口通信的应用 2、PC控制单片机IO口输出 3、51单片机控制实训指导及综合应用实例 4、51单片机给计算机发送数据 二、实验任务 单片机串口通信的应用&#xff0c;通过串口&#xff0c;我们的个人电脑和单片机系统进行通信。个人电脑作为上位机&#xff…

高能整理,性能测试-寻找TPS性能拐点与脚本Error报错排查(超细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 寻找tps性能拐点 …

DirectX3D 正交投影学习记录

所谓正交投影变换&#xff0c;就是已知盒状可视空间内任意点坐标(x,y,z)&#xff0c;求解垂直投影到xy平面的对应点坐标。 按照这个定义&#xff0c;xyz坐标系本身就是正交坐标系&#xff0c;盒状可视空间内任意点的坐标(x,y,z)投影到(x,y)平面&#xff0c;只要简单地丢弃z坐标…

3、Linux下安装

以下操作仅限于rh系列:支持rpm/yum安装方式&#xff0c;不支持deb/apt安装方式。 以下操作仅限于rh系列&#xff1a;支持rpm/yum安装方式&#xff0c;不支持 deb/apt安装方式。 1、在线下载安装包&#xff1a; wget https://downloads.mysql.com/archives/get/p/23/file/ m…

华为云云耀云服务器L实例评测|企业项目最佳实践之计划任务与Queue队列实践 (十)

十一、计划任务与Queue队列实践&#xff1a; 1. 计划任务&#xff1a; Linux环境下定时或者周期性的执行一些任务通常由cron这个守护进程来完成&#xff0c;这是一个系统自带的相对也比较方便的系统工具。 sudo apt-get install cron // 默认自带目录结构&#xff1a; 目录说…

leetcode-198.打家劫舍

1. 题目 2. 解答 dp[i]表示第i个位置的偷窃最大金额&#xff1b; room[i]表示第i间房间的现金&#xff1b; dp[0] room[0]; dp[1] max(room[0], room[1]); dp[i] max(dp[i-1], dp[i-2] room[i]); #include <stdio.h>int max(int a, int b) {return a > b? a:b;…

股票价格预测 | Python实现基于LSTM与Transfomer的股票预测模型(pytorch)

文章目录 效果一览文章概述LSTM模型原理时间序列模型从RNN到LSTMLSTM预测股票模型实现结语程序设计参考资料效果一览 文章概述 基于LSTM与Transfomer的股票预测模型 股票行情是引导交易市场变化的一大重要因素,若能够掌握股票行情的走势,则对于个人和企业的投资都有巨大的帮…

升级包版本之后Reflections反射包在springboot jar环境下扫描不到class排查过程记录

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是「奇点」&#xff0c;江湖人称 singularity。刚工作几年&#xff0c;想和大家一同进步&#x1f91d;&#x1f91d; 一位上进心十足的【Java ToB端大厂…

win11的右键菜单改成win10的样子

在终端复制一下命令 reg add “HKCU\Software\Classes\CLSID{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32” /f /ve 回车&#xff0c;会显示成功 再重启资源管理器。这步必须执行&#xff0c;否则是成功的&#xff0c;或者可能重启电脑会成功&#xff0c;但是我没有…

使用Vscode开发C#没有代码提示问题

很多小伙伴在使用Vscode去编写C#脚本的时候会发现没有代码提示&#xff0c;这样你的敲代码速度会变的很慢&#xff01; 错误使用方法 直接把C#脚本拖入到Vscode中进行编写&#xff0c;这样是不会有代码提示的&#xff01; 正确打开办式 Edit&#xff08;编辑&#xff09;…

解决 vscode使用Prettier格式化js文件报错:Cannot find module ‘./parser-babylon‘

报错如下&#xff1a; ["ERROR" - 11:48:58] Error formatting document. ["ERROR" - 11:48:58] Cannot find module ./parser-babylon Require stack: - d:\VueCode\VueProject\myqqmusic\node_modules\prettier\index.js - c:\Users\Administrator.SKY-2…

ARM汇编学习录 2 - 编码分析

本文记录笔者学习对应汇编指令相关编码知识 ARM32 首先阅读基础概念&#xff1a; ARM-instruction-set-encoding A32指令全部是32位且是4字节地址对齐. 位域如下 如何理解4字节地址对齐和指令长度&#xff1f; 0000139c <_start_main>:139c: e92d4800 …

pyqt5-tools的安装(深度学习)

本篇主要解决上篇深度学习pyqt安装失败的问题 PyQt是一个创建GUI应用程序的工具包。它是Python编程语言和Qt库的成功融合。Qt库是最强大的库之一。PyQt是由Phil Thompson 开发。在使用labelimg对图片做标签时&#xff0c;需要用到pyqt5-tools工具&#xff0c;尝试以下下载方式&…

06在IDEA中创建Java和Web工程,了解不同工程下的类路径,在IDEA中执行Maven命令

创建Java/Web模块 类路径的概述 IDEA中普通java项目中类路径的开始就是以src目录开始的路径,编译后的字节码文件和配置文件最终都会放在out目录下 Maven生成的目录结构中src/main目录下的java和resources目录都可以看作类路径的开始,编译后的字节码文件或资源文件会放在targ…

车辆车型识别系统python+TensorFlow+Django网页界面+算法模型

一、介绍 车辆车型识别系统。本系统使用Python作为主要开发编程语言&#xff0c;通过TensorFlow搭建算法模型网络对收集到的多种车辆车型图片数据集进行训练&#xff0c;最后得到一个识别精度较高的模型文件。并基于该模型搭建Django框架的WEB网页端可视化操作界面。实现用户上…