访问者模式:设计模式中的动态行为扩展

在软件开发中,设计模式是解决常见问题的成熟模板。访问者模式(Visitor Pattern)是行为型模式之一,它允许在不修改对象结构的情况下,为对象结构添加新的功能。本文将探讨访问者模式的核心概念、结构、实现方式以及它适用的场景。

一、访问者模式概述

访问者模式的目的是将算法与其所操作的对象分离,从而为对象结构添加新的操作或行为,而无需修改对象本身。这种分离使得算法可以独立于对象结构进行扩展。

二、核心组成

访问者模式包含以下几个核心角色:

  1. 访问者(Visitor):定义了对每一个元素类进行访问的行为,即对各个元素的访问方法。
  2. 元素(Element):定义了一个accept方法,用于接受访问者对象。
  3. 对象结构(Object Structure):包含多个元素,可以是集合、列表等,它有迭代器,可以遍历每个元素。
  4. 具体访问者(Concrete Visitor):实现了对各个具体元素类的访问操作。
  5. 具体元素(Concrete Element):实现了accept方法,通常是一个对象集合中的一个具体对象。

三、访问者模式的实现

以下是访问者模式的一个简单实现示例,我们将创建一个计算机部件的类结构,并定义一个访问者来计算部件的总价格。

3.1 定义元素

public interface ComputerPart {double price();void accept(ComputerPartVisitor visitor);
}public class Monitor implements ComputerPart {private double price;public Monitor(double price) {this.price = price;}@Overridepublic double price() {return price;}@Overridepublic void accept(ComputerPartVisitor visitor) {visitor.visit(this);}
}// 其他计算机部件类...

3.2 定义访问者

public interface ComputerPartVisitor {void visit(Monitor monitor);// 其他计算机部件的访问方法...
}public class PriceVisitor implements ComputerPartVisitor {private double totalPrice = 0.0;@Overridepublic void visit(Monitor monitor) {totalPrice += monitor.price();}// 其他访问方法...public double getTotalPrice() {return totalPrice;}
}

3.3 定义对象结构

import java.util.ArrayList;
import java.util.List;public class Computer {private List<ComputerPart> parts = new ArrayList<>();public void addPart(ComputerPart part) {parts.add(part);}public void removePart(ComputerPart part) {parts.remove(part);}public void accept(ComputerPartVisitor visitor) {for (ComputerPart part : parts) {part.accept(visitor);}}
}

四、适用场景

访问者模式适用于以下场景:

  1. 对象结构中对象的行为需要随着时间不断增长。
  2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作“污染”对象的结构类。
  3. 需要对对象结构进行动态的、多样的操作,而这些操作不能在对象结构中实现。

五、优点与缺点

优点

  • 扩展性:可以在不修改对象结构的情况下添加新的操作。
  • 分离关注点:算法与对象结构分离,使得两者可以独立变化。

缺点

  • 紧耦合:访问者依赖于具体元素类,这导致访问者与对象结构之间紧密耦合。
  • 增加对象数目:每增加一个新类型的对象结构,都需要在访问者接口中增加一个相应的操作。

六、总结

访问者模式是一种强大且灵活的设计模式,它允许我们在不修改对象结构的情况下,为对象结构添加新的功能。通过将算法从对象结构中分离出来,我们可以提高代码的可维护性和可扩展性。然而,这种模式也带来了一些缺点,如紧耦合和类数目的增加,因此在选择使用访问者模式时需要权衡利弊。

访问者模式是面向对象设计中的一个高级话题,理解它有助于深入掌握面向对象的基本原则和设计技巧。

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

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

相关文章

【自动驾驶技术栈学习】1-硬件《大话自动驾驶》| 综述要点总结 by.Akaxi

----------------------------------------------------------------------------------------------------------------- 致谢&#xff1a;感谢十一号线人老师的《大话自动驾驶》书籍&#xff0c;收获颇丰 链接&#xff1a;大话自动驾驶 (豆瓣) (douban.com) -------------…

618购物狂欢不知道怎么买?请收下这份好物清单,直接闭眼入!

在繁忙的618购物狂欢节来临之际&#xff0c;面对琳琅满目的商品&#xff0c;你是否感到无从下手&#xff1f;别担心&#xff0c;我们精心整理了一份好物清单&#xff0c;汇聚了各类热销与口碑兼具的精品。无论你是追求品质生活的消费者&#xff0c;还是寻找实惠好物的网购达人&…

实时网络监控 - 一目了然网络状况

网络问题排查一直是IT管理员头痛的问题。随着网络规模的不断扩大和业务复杂度的提升&#xff0c;如何快速定位和解决网络故障变得尤为关键。本文详细介绍了一款名为 AnaTraf 的网络流量分析工具,它能提供全流量回溯分析、实时网络监控、性能分析等功能,助力企业快速诊断和解决各…

JavaScript 根据标签名获取元素

要根据标签名获取元素&#xff0c;可以使用JavaScript中的 getElementsByTagName 方法。 getElementsByTagName 方法接受一个标签名作为参数&#xff0c;并返回一个包含指定标签名的元素列表。可以通过索引来访问列表中的元素。 以下是使用 getElementsByTagName 方法获取元素…

C#使用Exchange Web Services (EWS)通过流媒体订阅方式获取邮件列表、信息

代码 需要引用Microsoft.Exchange.WebServices包&#xff0c;using Microsoft.Exchange.WebServices.Data; public class EWSConnection{public static void doWork(){// 设置Exchange服务器URL和用户凭据string exchangeUrl "https://mail.xxx.com/EWS/Exchange.asmx&qu…

Nginx 部署两个前端项目【实战案例】 - alias / root 区别分析

文章目录 背景解决第 1 步:添加代理配置第 2 步:修改移动端 base 地址扩展 - alias/root 区别参考背景 项目中,使用 Nginx 代理前端项目,代码如下: location / {root /xxx/xxx-web;try_files $uri $uri/ /index.html;index index.html index.htm; }注意:禁止在 loca…

AI绘画Stable Diffusion换脸插件ReActor 不香了,新一代换脸神器 InstantID!

前 言 之前我介绍了 SD 中的一款换脸插件 ReActor&#xff0c;虽然好使&#xff0c;但是安装还是有些许麻烦的。 今天给小伙伴们介绍一款新型的换脸插件&#xff1a;InstantID&#xff0c;主要是使用 ControlNet 和 IP-Adapter 的组合来控制扩散过程中的面部特征。 一句话&a…

Hive的join操作

假设有三张表&#xff0c;结构和数据如下&#xff1a;-- 创建表 test_a,test_b,test_c CREATE TABLE test_a( id int, name string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY \t;--分别导入数据到三个表中 --test_a 1 a1 2 a2 4 a4 --test_b 1 b1 3 b3 4 b4 --…

【PyTorch】torch.backends.cudnn.benchmark 和 torch.backends.cudnn.deterministic

1. torch.backends.cudnn.benchmark 在 PyTorch 中&#xff0c;torch.backends.cudnn.benchmark 是一个配置选项&#xff0c;用于在运行时自动选择最优的卷积算法&#xff0c;以提高计算效率。这个设置特别针对使用 CUDA 和 cuDNN 库进行的运算&#xff0c;并在使用具有变化输…

【Vue探索之旅】初识Vue

文章目录 前言 渐进式框架​ 入门案例 完结撒花 前言 Vue (读音 /vjuː/&#xff0c;类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层&#xff0c;不仅易于上手&#x…

XWiki 服务没有正确部署在tomcat中,如何尝试手动重新部署?

1. 停止 Tomcat 服务 首先&#xff0c;您需要停止正在运行的 Tomcat 服务器&#xff0c;以确保在操作文件时不会发生冲突或数据损坏&#xff1a; sudo systemctl stop tomcat2. 清空 webapps 下的 xwiki 目录和 work 目录中相关的缓存 删除 webapps 下的 xwiki 目录和 work …

【实践】给proto的message添加自定义tag

背景 通常来说&#xff0c; 使用proto定义message的Field是使用下划线&#xff0c;比如&#xff1a; # proto定义 message Req {string key_name 1; }# 生成的.pb.go 中req的定义type Req struct {state protoimpl.MessageStatesizeCache protoimpl.SizeCacheun…

angular13 自定义组件全项目都可用 自存

1.定义自定义组件 使用命令创建一个组件 但删除它在你的module里的声明&#xff0c;因为会报错只能引用一次 在本组件中创建一个module文件&#xff0c;引入刚才的组件component.ts import { NgModule } from angular/core; import { CommonModule } from angular/common; im…

[ES] ElasticSearch节点加入集群失败经历分析主节点选举、ES网络配置 [publish_address不是当前机器ip]

背景 三台CentOS 7.6.1虚拟机&#xff0c; 每台虚拟机上启动一个ElasticSearch 7.17.3&#xff08;下面简称ES&#xff09;实例 即每台虚拟机上一个ES进程&#xff08;每台虚拟机上一个ES节点&#xff09; 情况是&#xff1a; 之前集群是搭建成功的, 但是今天有一个节点一…

【运维实践项目|004】:企业网络性能优化升级项目

目录 项目名称 项目背景 项目目标 项目成果 我的角色与职责 我主要完成的工作内容 本次项目涉及的技术 本次项目遇到的问题与解决方法 本次项目中可能被面试官问到的问题及答案 问题1&#xff1a;你是如何分析网络瓶颈的&#xff1f; 问题2&#xff1a;你是如何实施网…

PHP超级全局变量 | 全栈: [表单post提交数据(姓名,密码,文件)]

超级全局变量 特点&#xff1a;预定义变量无需创建 作用&#xff1a;用于存储来自执行环境的特殊信息&#xff0c;如HTTP请求数据、服务器信息、会话数据 常见类别 $_GET 用于收集表单数据&#xff0c;当表单的method为get时&#xff0c;数据会通过URL传递。例如&#xff0c…

函数编辑器调研及设计开发

前言&#xff1a;在产品研发中需要一款可嵌入web开发的代码及函数编辑器&#xff0c;本文从功能&#xff0c;扩展&#xff0c;外观/交互&#xff0c;维护/社区&#xff0c;兼容性&#xff0c;开源与否等方面考虑&#xff0c;进行对比筛选 1、编辑器统计数据 市面上编辑器有很…

Windows电脑使用Docker安装AList网盘神器并配置公网地址打造私人云存储空间

文章目录 前言1. 使用Docker本地部署Alist1.1 本地部署 Alist1.2 访问并设置Alist1.3 在管理界面添加存储 2. 安装cpolar内网穿透3. 固定Alist公网地址 前言 本文和大家分享如何在Windows系统使用Docker本地部署Alist全平台网盘神器&#xff0c;然后结合cpolar内网穿透工具实现…

全面解析:分布式光伏系统的概念、优缺点和应用

光伏发电领域中&#xff0c;分布式和集中式光伏是两种主要应用模式。集中式电站占地面积大&#xff0c;受国家土地政策制约严重&#xff0c;且我国土地资源又相当紧缺&#xff0c;而分布式光伏电站因接网便利、场地灵活等特点&#xff0c;近年来发展迅速&#xff0c;越来越多的…

P3853 [TJOI2007] 路标设置

题目描述: 题目背景 B 市和 T 市之间有一条长长的高速公路&#xff0c;这条公路的某些地方设有路标&#xff0c;但是大家都感觉路标设得太少了&#xff0c;相邻两个路标之间往往隔着相当长的一段距离。为了便于研究这个问题&#xff0c;我们把公路上相邻路标的最大距离定义为…