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

【从零入门23种设计模式24】行为型之访问者模式

一、访问者模式核心定义

访问者模式是行为型设计模式的一种,核心目的是:

将数据结构与对数据的操作分离,使得操作可以独立于数据结构变化;定义一个作用于某对象结构中各元素的操作,而无需改变各元素的类。

简单来说:把对不同类型对象的操作(如计算、校验、导出)封装成独立的 “访问者” 类,数据对象接受访问者的访问并调用对应操作,实现 “数据不动,操作动”

核心解决的问题
  1. 解耦数据结构与操作:数据对象(如订单、商品、用户)的结构稳定,但对数据的操作(如统计、导出、校验)频繁变化时,无需修改数据类;
  2. 复用操作逻辑:同一套操作(如导出 Excel)可作用于不同类型的数据对象;
  3. 集中管理同类操作:所有数据对象的 “导出” 操作集中在ExportVisitor中,而非分散在各个数据类中;
  4. 支持多态操作:不同类型的数据对象对同一访问者会执行不同的操作(如订单导出、商品导出逻辑不同);
  5. 符合开闭原则:新增操作只需新增访问者类,无需修改数据对象类。
生活类比
  • 场景 1:商场巡检
    • 数据结构:商场中的不同元素(店铺、仓库、办公室);
    • 访问者:不同的巡检人员(安全巡检员、卫生巡检员、消防巡检员);
    • 核心:每个巡检人员(访问者)对不同场所(数据对象)执行不同的巡检操作,场所只需接受访问并配合巡检,无需修改自身逻辑。
  • 场景 2:财务审计
    • 数据结构:公司的不同资产(固定资产、流动资产、无形资产);
    • 访问者:审计人员(税务审计、财务审计、合规审计);
    • 核心:审计人员(访问者)对不同资产(数据对象)执行审计操作,资产类无需修改,新增审计类型只需新增访问者。
  • 场景 3:电商数据统计
    • 数据结构:订单、商品、用户;
    • 访问者:统计访问者(销售额统计、用户活跃度统计、商品销量统计);
    • 核心:统计访问者遍历所有数据对象,执行对应统计操作,新增统计维度只需新增访问者。
标准角色
角色职责类比(商场巡检场景)代码定位
抽象元素(Element)定义接受访问者的接口(accept(Visitor visitor)),所有数据对象实现该接口场所接口(Place):accept(Inspector visitor)接口 / 抽象类
具体元素(ConcreteElement)实现抽象元素接口,调用访问者的对应方法(如visitor.visitShop(this)店铺(Shop)、仓库(Warehouse)数据对象类
抽象访问者(Visitor)定义对所有具体元素的访问方法(visitShop(Shop shop)visitWarehouse(Warehouse warehouse)巡检员接口(Inspector):checkShop()checkWarehouse()接口 / 抽象类
具体访问者(ConcreteVisitor)实现抽象访问者接口,封装对不同元素的具体操作逻辑安全巡检员(SafetyInspector)、卫生巡检员(CleanlinessInspector)操作实现类
对象结构(ObjectStructure)管理元素集合,提供遍历元素的方法,供访问者遍历所有元素执行操作商场(Mall):管理所有场所,提供遍历方法集合管理类
核心 UML 类图

二、电商数据统计

以 “电商数据统计” 为例,实现访问者模式的核心逻辑 —— 数据对象(订单、商品、用户)结构稳定,统计操作(销售额、销量、活跃度)封装为访问者,新增统计维度只需新增访问者,无需修改数据类。

1. 步骤 1:定义抽象元素(数据对象接口)
/** * 抽象元素:电商数据对象接口(定义接受访问者的方法) */ public interface EcommerceElement { /** * 接受访问者访问 */ void accept(EcommerceVisitor visitor); }
2. 步骤 2:实现具体元素(订单 / 商品 / 用户)
/** * 具体元素1:订单 */ public class OrderElement implements EcommerceElement { private String orderId; // 订单ID private double amount; // 订单金额 private int productCount; // 商品数量 public OrderElement(String orderId, double amount, int productCount) { this.orderId = orderId; this.amount = amount; this.productCount = productCount; } // 核心:接受访问者,调用访问者的订单访问方法 @Override public void accept(EcommerceVisitor visitor) { visitor.visitOrder(this); } // Getter public String getOrderId() { return orderId; } public double getAmount() { return amount; } public int getProductCount() { return productCount; } } /** * 具体元素2:商品 */ public class ProductElement implements EcommerceElement { private String productId; // 商品ID private String productName; // 商品名称 private int salesCount; // 销量 public ProductElement(String productId, String productName, int salesCount) { this.productId = productId; this.productName = productName; this.salesCount = salesCount; } @Override public void accept(EcommerceVisitor visitor) { visitor.visitProduct(this); } // Getter public String getProductId() { return productId; } public String getProductName() { return productName; } public int getSalesCount() { return salesCount; } } /** * 具体元素3:用户 */ public class UserElement implements Ecomm
http://www.jsqmd.com/news/495126/

相关文章:

  • 给AI老板植入幻觉:让它自认是饮水机
  • OpenAI 新模型 GPT - 5.4 系列:小身材能否撬动大市场?
  • 总结GRG石膏制品选购要点,天津好用的品牌有哪些 - mypinpai
  • 探索 FDTD 算法仿真超透镜:从参数调整到聚焦实现
  • 黑马点评-用JMeter测试缓存重建时,HTTP请求的响应结果的data为空
  • 二分题目集
  • 2026年GRG石膏制品优质供应商推荐,费用怎么算 - 工业设备
  • 项目实训(一):项目基础框架与 FastAPI 后端创建
  • 深度解析 `utf8mb4` 和 `utf8mb4_unicode_ci`:从原理到实战,避坑指南全解析
  • SSR驱动220V需TVS/MOV而非RCD
  • 2026年黑龙江高性价比二手房翻新企业排名,值得选的品牌 - 工业推荐榜
  • Claude国内镜像站实测:可扩展监督与宪法AI,推理架构的范式革命
  • 关于防抖和节流
  • 操作步骤分享:DeepSeek转Word文档的正确步骤
  • 探寻2026正极材料废气焚烧炉推荐厂商,选购要点有哪些 - myqiye
  • OpenClaw 高效配置与集成指南:从模型选择到 API 对接
  • Meta羊驼LLaMA的崛起与争议:开源AI的史诗级故事
  • 讲讲靠谱的轻集料混凝土LC5.0源头工厂,京津冀地区有哪些推荐? - 工业品牌热点
  • 英语六级作文历年真题及范文模版汇总PDF电子版(2015-2025年6月)
  • 风爆远征英雄年代怀旧服:初心不改热血依旧,英雄年代怀旧服必玩国战经典
  • HomeAssistant——MQTT设备实体创建
  • 【深度学习实战】巧用“噪声”画出心脏:扩散模型(Diffusion Model)在超声影像合成中的破局
  • 2026年轻集料混凝土排名,揭秘质量好的B型及A型价格多少 - 工业品网
  • 25只股票组合:彼得林奇的投资建议
  • 两数之和(leetcode一百复盘)
  • Kagi小网络:挖掘互联网角落,放大真实人类声音
  • 路由器成“二传手”?eNSP实战:一台DHCP服务器如何管遍全网段!(附抓包详解)
  • 1Password Unified Access:应对 AI 代理凭证管理挑战
  • COMSOL电池组优化:高倍率充放电下的PCM相变技术结合液冷散热系统
  • 能用脚本就别用Agent。