软件设计模式与体系结构-设计模式-行为型软件设计模式-访问者模式

news2024/11/23 10:02:49

目录

  • 二、访问者模式
    • 概念
    • 代码
    • 类图
    • 实例一:名牌运动鞋专卖店销售软件
    • 实例二:计算机部件销售软
    • 优缺点
    • 适用场合
    • 课程作业

二、访问者模式

概念

  1. 对于系统中的某些对象,它们存储在同一个集合中,具有不同的类型
  2. 对于该集合中的对象,可以接受一类被称为访问者的对象来访问
  3. 不同的访问者其访问方式有所不同

目的:
封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变

模式动机:
为不同类型的元素提供多种访问操作方式,且可以在不修改原有系统的情况下增加新的操作方式

在这里插入图片描述

缺点:将所有的税率运算分布到不同的结点类使得系统不容易理解、维护与改变。
如果要增加一个新的功能,则要在很多结点类都写入新的代码,且要重新编译所有的类。
当税率变化时要修改每个结点上的calculateTax()代码。
因此,该设计的可扩展性和可维护性都不好。

解决方案:分离“Tax”类及其“calculateTax()”功能。
将所有结点的税额计算方法都从原来的类中分离出来,放入另外一个独立的类,叫做“TaxCalculation”类,设计图如下。
设计思想:将原来分布于各结点中的计算税额的方法都放在一个TaxCalculation类中。当要计算某个结点的税额时,则调用TaxCalculation中某个相应的方法进行计算。
在这里插入图片描述

代码

访问者模式(Visitor Pattern)是一种行为型设计模式,用于在不改变被访问对象的结构的情况下,定义对其元素的新操作。访问者模式将数据结构和对数据的操作分离开来,使得操作可以独立变化而不影响数据结构。

在访问者模式中,有以下几个角色:

  1. 访问者(Visitor):定义了对不同元素的访问操作,每个具体访问者都实现了对应的访问方法,用于处理特定类型的元素。

  2. 具体访问者(Concrete Visitor):实现了访问者定义的访问方法,具体处理不同类型元素的操作。

  3. 元素(Element):定义了接受访问者访问的接口,可以是抽象类或接口。

  4. 具体元素(Concrete Element):实现了元素定义的接口,具体元素可以有不同的类型,每个具体元素都可以接受访问者的访问。

  5. 对象结构(Object Structure):包含元素的集合,可以是一个容器,也可以是一个复杂的数据结构。

下面是一个简单的访问者模式的示例代码,以展示其使用方式和实现原理:

// 定义元素接口
interface Element {
    void accept(Visitor visitor);
}

// 具体元素A
class ConcreteElementA implements Element {
    public void accept(Visitor visitor) {
        visitor.visitConcreteElementA(this);
    }
    
    public String operationA() {
        return "具体元素A的操作";
    }
}

// 具体元素B
class ConcreteElementB implements Element {
    public void accept(Visitor visitor) {
        visitor.visitConcreteElementB(this);
    }
    
    public String operationB() {
        return "具体元素B的操作";
    }
}

// 定义访问者接口
interface Visitor {
    void visitConcreteElementA(ConcreteElementA element);
    void visitConcreteElementB(ConcreteElementB element);
}

// 具体访问者
class ConcreteVisitor implements Visitor {
    public void visitConcreteElementA(ConcreteElementA element) {
        System.out.println("访问者对" + element.operationA() + "的操作");
    }
    
    public void visitConcreteElementB(ConcreteElementB element) {
        System.out.println("访问者对" + element.operationB() + "的操作");
    }
}

// 对象结构
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 VisitorPatternExample {
    public static void main(String[] args) {
        // 创建对象结构
        ObjectStructure objectStructure = new ObjectStructure();

        // 添加具体元素A和B
        objectStructure.addElement(new ConcreteElementA());
        objectStructure.addElement(new ConcreteElementB());

       

// 创建具体访问者
        Visitor visitor = new ConcreteVisitor();

        // 对对象结构中的元素进行访问操作
        objectStructure.accept(visitor);
    }
}

在上述示例代码中,访问者模式的核心在于访问者(Visitor)和元素(Element)的交互。具体的访问者定义了访问不同元素的方法,而具体元素实现了接受访问者访问的接口。通过对象结构将元素组织起来,并调用访问者的访问方法,实现对元素的访问操作。

访问者模式的优点包括:

  • 将数据结构和操作解耦,使得新增访问操作变得容易。
  • 可以对元素的操作进行扩展,而不需要修改元素的结构。
  • 符合开闭原则,增加新的访问者只需要新增具体访问者,而不需要修改其他代码。

然而,访问者模式也有一些限制和注意事项:

  • 增加新的元素可能会导致访问者接口的修改,从而需要修改所有的具体访问者。
  • 对象结构中的元素类型较多时,会导致具体访问者的访问方法过多,增加了维护的复杂性。
  • 访问者模式适用于数据结构相对稳定,但经常需要新增操作的场景,对于数据结构变化频繁的场景,使用访问者模式可能不合适。

总而言之,访问者模式提供了一种灵活的方式来对数据结构的元素进行新的操作,同时也将访问逻辑与元素的结构解耦,使得系统更加灵活、可扩展和易于维护。

类图

访问者模式:表示一个作用于某对象结构中的个元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作
访问者模式是一种对象行为型模式

在这里插入图片描述
首先分为两个部分,一是元素类,而是访问者类
先抽象再具体
在访问者类里要有访问元素的方法visitXXX(抽象元素父类做参数)之类的
在元素类里要有接受访问的方法,比如accept(抽象访问者父类做参数)等

在这里插入图片描述

实例一:名牌运动鞋专卖店销售软件

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在客户程序中将直接创建运动鞋子类与访问者子类的对象,然后直接调用运动鞋子类的 accept 方法。根据用户输入的所购买鞋的数量和单价来计算总价和获得相应特点的功能分别由 Visitor 类的两个子类 PriceVisitor 和 ShoeInfoVisitor 来实现。访问者类图如下。

实例二:计算机部件销售软

在这里插入图片描述
在这里插入图片描述

优缺点

优点:

  1. 使得增加新的访问操作变得很容易
  2. 将有关元素对象的访问行为集中到一个访问者对象中,而不是分散到一个个的元素类中。
  3. 可以跨过类的等级结构访问属于不同的等级结构的元素类
  4. 让用户能够在不修改现有类层次结构的情况下,定义该类层次结构的操作

缺点:

  1. 增加新的元素类很困难,违背了“开闭原则”的要求
  2. 破坏封装。访问者模式要求访问者对象访问并调用每一个元素对象的操作,这意味着元素对象有时候必须暴露一些自己的内部操作和内部状态,否则无法供访问者访问。

适用场合

对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作

课程作业

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/723641.html

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

相关文章

力扣算法练习(三)

目录 1. N 字形变换&#xff08;6&#xff09; 题解一&#xff08;力扣官方解析力扣&#xff09; 题解二&#xff08;官方解法&#xff09; 题解三&#xff08;力扣&#xff09; 2. 整数反转&#xff08;7&#xff09; 题解一 题解二 题解三&#xff08;官方解析&#…

车辆在刹车不及时导致与行人发生碰撞事故,产生出险记录

车辆在刹车不及时导致与行人发生碰撞事故&#xff0c;是一种常见的交通事故。当发生此类事故时&#xff0c;车主需要及时处理保险理赔事宜&#xff0c;同时也需要了解车辆出险、理赔、事故记录情况&#xff0c;以便更好地维护车辆和自身权益。为方便车主查询车辆出险、理赔、事…

UI自动化测试工具能够做的几件事情

UI自动化测试工具在软件开发过程中发挥着重要的作用。它们可以帮助测试人员自动执行各种用户界面操作&#xff0c;验证界面功能和性能&#xff0c;提高测试效率和质量。本文将介绍UI自动化测试工具能够做的几件事情&#xff0c;并解释为什么它们对测试人员来说非常有价值。 首先…

UE5 plugin failed to load because module could not be found

解决方法&#xff1a;将提示缺少的插件加入到.uproject中即可解决

Liunx系统编程:系统层面上的文件IO接口

目录 一. 如何在系统层面上理解文件 二. 语言层面上的文件IO函数 三. Linux操作系统提供的IO接口 3.1 open接口 -- 打开文件 3.2 close接口 -- 关闭文件 3.3 write接口 -- 向文件中写内容 3.4 read接口 -- 从文件中读取内容 四. 总结 一. 如何在系统层面上理解文件 在L…

axios文件上传和 Content-Type类型介绍

Content-Type的作用是什么&#xff1f; Content-Type: 用于在请求头部指定资源的类型和字符编码。 请求头中的content-type&#xff0c;就是 B端发给S端的数据类型描述 。 即告诉服务器端&#xff0c;我给你传的数据是某种类型的。 服务器端针对不同类型的数据&#xff0c;做法…

分布式监控Zabbix的部署

zabbix 6.0 一、zabbinxzabbix的简介Zabbix 6.0 功能组件zabbix的监控原理zabbix 6.0的特性 二、zabbix 6.0 部署部署 Nginx PHP 环境并测试部署数据库&#xff0c;要求 MySQL 5.7 或 Mariadb 10.5 及以上版本编译安装 zabbix Server 服务端部署 Web 前端&#xff0c;进行访问…

HTTP的一些概念

文章目录 HTTP定义URI&URL HTTP 常见的状态码http 首部请求首部字段响应首部字段为cookie服务的首部字段get请求和post请求及区别GET 和 POST 方法是否安全和幂等 HTTP特性HTTP&#xff08;1.1&#xff09; 的优点有哪些HTTP/1.1 的缺点HTTP/1.1 的性能HTTP/1.1 相比 HTTP/…

[MySQL]表的操作

[MySQL]表的操作 文章目录 [MySQL]表的操作1. 创建表2. 创建表的示例3. 查看表4. 修改表5. 删除表6. 关于表操作 1. 创建表 语法&#xff1a; CREATE TABLE [IF NOT EXISTS] table_name(field1 datatype1 [COMMENT 注释信息],field2 datatype2 [COMMENT 注释信息],field3 dat…

伦敦金实时报价技术分析

技术分析是从伦敦金的价格行为&#xff0c;来分析未来走势变化的方法。伦敦金市场的变化可以有多种表现形式&#xff0c;其中根据市场价格、成交量等的变化&#xff0c;可以探索出一些规律&#xff0c;技术分析者通过对市场过去和现在的行为&#xff0c;应用数学原理去理解价格…

【Python】基于Python的机器学习分类的模型选择:交叉验证和模型质量评估

目录 1 简介2 思路分解与说明3 完整代码 1 简介 最近完成一个工作&#xff0c;就基于一些表格化的数据进行机器学习分类。 由于分类是研究中的关键步骤&#xff0c;所以首先要选择到底哪个模型适合我们的分类任务。 比较传统且经典的选择方法就是用交叉验证。 交叉验证是什么可…

openwrt使用记录

背景&#xff1a; 平时在vmware中做实验时候&#xff0c;经常需要在不同的机器上下载一些github上的项目进行调试&#xff0c;之前解决方案是在路由器层小米ac2100上装openwrt&#xff0c;试用一番发现太卡了。放弃&#xff0c;这次在vmware中安装作为小米ac2100的旁路由 规划…

推荐五款优秀,可替代商业软件的开源软件

​ 在日常的使用中&#xff0c;我们需要使用各种软件来提高我们的工作效率或者进行创意的表达。然而&#xff0c;商业软件价格昂贵&#xff0c;某些国产软件又充斥着广告。因此&#xff0c;开源软件成为了一个不错的选择&#xff0c;以下是我推荐的五款优秀的开源软件。 图片浏…

一文get,最容易碰上的接口自动化测试问题汇总

本篇文章分享几个接口自动化用例编写过程遇到的问题总结&#xff0c;希望能对初次探索接口自动化测试的小伙伴们解决问题上提供一小部分思路。 sql语句内容出现错误 空格&#xff1a;由于有些字段判断是变量&#xff0c;需要将sql拼接起来&#xff0c;但是在拼接字符串时没有…

手写操作系统--完善内核加载器之内存检测

这一篇我们来完善内核加载器的功能&#xff0c;我们知道内存是很重要的区域&#xff0c;我们需要对内存有个大致的描述&#xff0c;哪些可用&#xff0c;那些不可用&#xff0c;内存有多大。因此在内核加载器中我们需要对内存进行检测。内存检测的方法翻译文档如下&#xff1a;…

DAY39:贪心算法(八)无重叠区间+划分字母区间+合并区间

文章目录 435.无重叠区间思路完整版注意点 右区间排序 763.划分字母区间思路完整版如何确定区间分界线debug测试时间复杂度 总结 56.合并区间思路最开始的写法&#xff1a;直接在原数组上修改debug测试 修改版时间复杂度总结 435.无重叠区间 给定一个区间的集合 intervals &am…

“钓鱼”网站也有https?如何一招识破?

作为企业网站安全建设的基础设施&#xff0c; SSL证书可以对数据进行加密传输&#xff0c;保护数据在传输过程中不被监听、截取和篡改&#xff0c;因此部署了SSL证书的网站会比传统的http协议更加安全&#xff0c;也更受主流操作系统和浏览器的信任。 然而随着SSL证书的普及&a…

AI做PPT,五分钟搞定别人一天的量,最喜欢卷PPT了

用AI做PPT 主题生成大纲制作PPT 主题生成大纲 如何使用人工智能工具&#xff0c;如ChatGPT和mindshow&#xff0c;快速生成PPT。 gpt国内版 制作PPT&#xff0c;你可能只有一个主题&#xff0c;但没有明确的提纲或思路。 问gpt&#xff1a;计算机视觉的周工作汇报。我这周学…

MyBatis 与 Hibernate 有哪些不同?

ORM框架的选择与适用场景 MyBatis和Hibernate都是Java领域中流行的面向关系型数据库的ORM&#xff08;对象关系映射&#xff09;框架。它们的共同目标是简化开发人员操作数据库的工作&#xff0c;提供便捷的持久化操作。然而&#xff0c;两者在设计理念和适用场景上有所不同。…

Zabbix6.0 的部署

目录 一、概述 二、 zabbix 1.zabbix简介 2.zabbix监控原理 3. Zabbix 6.0 新特性 3.1Zabbix server高可用防止硬件故障或计划维护期的停机 3.2 Zabbix 6.0 LTS新增Kubernetes监控功能&#xff0c;可以在Kubernetes系统从多个维度采集指标 4. Zabbix 6.0 功能组件 4.1Z…