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

【从零入门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

Read more

cpolar远程辅助Open-Lovable实现随时随地克隆网页超实用

cpolar远程辅助Open-Lovable实现随时随地克隆网页超实用

Open-Lovable 是一款面向前端开发者的开源工具,核心功能是将任意网页克隆为可编辑的 React 应用,还支持多类 AI 模型辅助生成代码,适配新手学习、中小企业原型开发等场景。它的优点很贴合实际需求:拆分代码组件清晰,保留完整 CSS 样式,能大幅减少手动搭建页面框架的时间,比如新手学习电商网站布局时,不用再逐行拆解复杂的源代码,直接克隆后就能看清 header、footer 等组件的逻辑,中小企业做产品原型时,克隆同类网页后稍作修改就能快速出效果。 使用这款工具时也有一些实用的小提醒💡:克隆的网页仅能还原静态布局和样式,像登录态、动态交互这类内容无法完整复刻,而且使用前需要准备好 E2B、Firecrawl 等平台的 API 密钥,密钥保管要注意隐私,避免外泄造成不必要的损失。 不过 Open-Lovable 默认只能在本地局域网内使用,这会带来不少不便:比如开发者在家调试的克隆项目,想让公司的设计师远程查看效果,只能通过传文件、远程协助的方式,不仅耗时,还可能出现版本不一致的问题;要是出差在外需要修改克隆的代码,没法直接访问本地的工具,只能等回到电脑前操作,耽误工作

By Ne0inhk
《C/C+++ Boost 轻量级搜索引擎实战:架构流程、技术栈与工程落地指南——构造正/倒排索引(中篇)》

《C/C+++ Boost 轻量级搜索引擎实战:架构流程、技术栈与工程落地指南——构造正/倒排索引(中篇)》

前引:这是一个聚焦基础搜索引擎核心工作流的实操项目,基于 C/C++ 技术生态落地:从全网爬虫抓取网页资源,到服务器端完成 “去标签 - 数据清洗 - 索引构建” 的预处理,再通过 HTTP 服务接收客户端请求、检索索引并拼接结果页返回 —— 完整覆盖了轻量级搜索引擎的端到端逻辑。项目采用 C++11、STL、Boost 等核心技术栈,搭配 CentOS 7 云服务器 + GCC 编译环境(或 VS 系列开发工具)部署,既适配后端工程的性能需求,也能通过可选的前端技术(HTML5/JS 等)优化用户交互,是理解搜索引擎底层原理与 C++ 工程实践的典型案例 目录 【一】Jieba分词工具 【二】正/倒排索引结构设计

By Ne0inhk
深入理解 MySQL:索引、数据库设计、事务与视图

深入理解 MySQL:索引、数据库设计、事务与视图

在日常的后端开发中,MySQL 作为一款经典的关系型数据库,是我们数据存储和管理的核心工具。想要让 MySQL 发挥出最优性能,同时保证数据的完整性、一致性和安全性,就必须深入掌握索引、数据库设计、事务和视图这些核心知识点。本文将结合实战场景,详细拆解这四大核心模块的使用逻辑与最佳实践。 一、索引:提升查询效率的 “加速器” 索引是 MySQL 优化查询性能的关键手段,其本质是一种特殊的数据结构(如 B + 树),能够帮助数据库快速定位到目标数据,避免全表扫描带来的性能损耗。 1. 索引的核心类型 (1)普通索引 最基础的索引类型,无唯一性约束,仅用于加速查询。 * 创建方式: -- 直接创建 CREATE INDEX idx_username ON user (username); -- 修改表结构添加 ALTER TABLE user ADD

By Ne0inhk
2025版最详细WebStorm下载安装教程(详细图解)

2025版最详细WebStorm下载安装教程(详细图解)

目录 一、前言 二、WebStorm的下载安装 1、下载WebStorm 2、安装WebStorm 3、首次启动WebStorm 一、前言 前端一般就是用WebStorm或者是VSCode,Jetbrains家的ide一般都比较重,VSCode相对而言就轻快一点。主要还是看大家自己喜欢哪个就下哪个,我个人电脑内存是32G所以我一直用Jetbrains家的软件体验不错。本博客记录一下WebStorm的安装流程,大家自行参考 然后WebStorm从24年10月开始就是免费的了,所以不需要任何许可证直接下了就能用,并且也不需要像Java和Python那样配JDK和解释器,整体还是很简单的 二、WebStorm的下载安装 1、下载WebStorm 打开浏览器,访问JetBrains的官方网址,点击如下网址能直接跳转到WebStorm的下载页面: Download WebStorm: The JavaScript and TypeScript IDE by JetBrains 选择好自己的系统,然后直接点击Download即可 等待安装包下载完成,网速快

By Ne0inhk