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

Java 工厂模式 + 策略模式实战:工具管理器的设计与实现

在日常开发中,我们经常会遇到「需要根据不同的业务逻辑选择不同实现类」的场景。比如:文件操作可能有读取、写入、修改、删除等多种方式,如果我们在业务代码中使用大量的 if-else 来区分,会导致代码臃肿且难以维护。

本文将结合 工厂模式(Factory Pattern)策略模式(Strategy Pattern),通过一个 工具管理器(ToolManager) 的案例,来展示如何优雅地管理和调用不同的工具。


一、模式介绍

1. 工厂模式

工厂模式的核心思想是:将对象的创建与使用解耦
调用方不需要关心对象的具体实现,而只需要通过工厂方法获取对象即可。

在本文中,ToolManager 就是一个工厂,负责 统一注册和管理所有工具实例

2. 策略模式

策略模式强调:定义一系列算法(策略),并且可以在运行时自由切换
调用方只需要依赖抽象接口,而不需要知道具体的实现细节。

在本文中,每个工具(如 FileReadToolFileWriteTool)就是一个具体策略,统一实现了 BaseTool 抽象类。


二、使用场景

这种「工厂模式 + 策略模式」的组合,非常适合以下场景:

  1. 多实现类管理
    比如支付系统中的 微信支付 / 支付宝支付 / 银行卡支付,都可以作为不同的策略,由工厂统一管理。

  2. 动态扩展
    新增一种工具(比如 FileUploadTool),只需要实现 BaseTool 并交给工厂管理,而不需要改动原有逻辑,符合 开闭原则

  3. 业务逻辑解耦
    调用方只依赖抽象接口(BaseTool),而不依赖具体实现,业务逻辑更加清晰。


三、代码示例

下面给出完整的示例代码,使用 Spring + Hutool 结合实现。

1. 定义工具基类(抽象类)

package com.ming.mingaicode.ai.tools;import cn.hutool.json.JSONObject;/*** 工具基类,定义所有工具的通用接口*/
public abstract class BaseTool {public abstract String getToolName();public abstract String getDisplayName();public String generateToolRequestResponse() {return String.format("\n\n[选择工具🔧] %s\n\n", getDisplayName());}public abstract String generateToolExecutedResult(JSONObject arguments);
}

2. 定义多个工具实现类(具体策略)

文件目录读取工具
@Slf4j
@Component
public class FileDirReadTool extends BaseTool{@Overridepublic String getToolName() { return "readDir"; }@Overridepublic String getDisplayName() { return "读取目录"; }@Overridepublic String generateToolExecutedResult(JSONObject arguments) {String relativeDirPath = arguments.getStr("relativeDirPath");if (StrUtil.isEmpty(relativeDirPath)) {relativeDirPath = "根目录";}return String.format("[工具调用] %s %s", getDisplayName(), relativeDirPath);}
}
文件修改工具
@Slf4j
@Component
public class FileModifyTool extends BaseTool{@Overridepublic String getToolName() { return "modifyFile"; }@Overridepublic String getDisplayName() { return "修改文件"; }@Overridepublic String generateToolExecutedResult(JSONObject arguments) {String relativeFilePath = arguments.getStr("relativeFilePath");String oldContent = arguments.getStr("oldContent");String newContent = arguments.getStr("newContent");return String.format("""[工具调用] %s %s替换前:```%s```替换后:```%s```""", getDisplayName(), relativeFilePath, oldContent, newContent);}
}
文件写入工具
@Slf4j
@Component
public class FileWriteTool extends BaseTool{@Overridepublic String getToolName() { return "writeFile"; }@Overridepublic String getDisplayName() { return "写入文件"; }@Overridepublic String generateToolExecutedResult(JSONObject arguments) {String relativeFilePath = arguments.getStr("relativeFilePath");String suffix = FileUtil.getSuffix(relativeFilePath);String content = arguments.getStr("content");return String.format("""[工具调用] %s %s```%s%s```""", getDisplayName(), relativeFilePath, suffix, content);}
}

(其他工具如 FileReadToolFileDeleteTool 也类似,不再赘述)


3. 工厂管理器(ToolManager)

@Slf4j
@Component
public class ToolManager {@Resourceprivate BaseTool[] tools;private final Map<String, BaseTool> toolMap = new HashMap<>();@PostConstructpublic void initTools() {for (BaseTool tool : tools) {toolMap.put(tool.getToolName(), tool);log.info("注册工具: {} -> {}", tool.getToolName(), tool.getDisplayName());}log.info("工具管理器初始化完成,共注册 {} 个工具", toolMap.size());}public BaseTool getTool(String toolName) {return toolMap.get(toolName);}public BaseTool[] getAllTools() {return tools;}
}

4. 使用方式

// 处理工具请求
case TOOL_REQUEST -> {BaseTool tool = toolManager.getTool(toolRequestMessage.getName());return tool.generateToolRequestResponse();
}// 处理工具执行结果
case TOOL_EXECUTED -> {BaseTool tool = toolManager.getTool(toolExecutedMessage.getName());String result = tool.generateToolExecutedResult(jsonObject);return String.format("\n\n%s\n\n", result);
}

四、方法解析

  1. 抽象基类 BaseTool

    • 统一了所有工具的接口(名字、展示名、执行结果格式化)。

    • 保证扩展新工具时,调用方无需修改原有逻辑。

  2. 具体工具类(策略)

    • 每个工具都实现了自己的 generateToolExecutedResult 方法,遵循 策略模式

  3. ToolManager 工厂

    • 自动扫描所有 BaseTool 的子类(Spring 注入)。

    • 通过 Map 保存工具名称和实例的映射,支持快速查找和调用。


五、总结

本文通过 工厂模式 + 策略模式 结合的方式,构建了一个可扩展、可维护的 工具管理器

  • 工厂模式负责统一管理实例

  • 策略模式负责封装不同的业务逻辑

  • 新增功能时,只需要 新增一个实现类,无需修改现有代码,真正做到 开闭原则

这种设计思想在 支付系统、权限系统、AI 工具调用 等场景下都有广泛应用,能够显著提升代码的可维护性和扩展性。

http://www.dtcms.com/a/390963.html

相关文章:

  • 污水处理厂远程调试与智能化运维解决方案
  • 【提示工程】Ch2-提示技术(Prompt Technique)
  • vLLM - Worker
  • GitHub上面仓库名写错了,怎么改
  • 项目中的图形验证码是前端还是后端实现?
  • ✅ 基于Scrapy与朴素贝叶斯的校园舆情监测与预警系统 Django+B/S架构 可视化大屏 机器学习
  • Unity UI 插件 | Easy Popup System
  • AI证件照制作 API 快速生成证件照
  • @RequestParam和 @RequestBody能一起用吗
  • 构建高效的电商爬虫代理池:从架构设计到实战优化
  • 使用cJSON库实现JSON与C结构体的互转
  • Cursor :Python 运行路径设置自定义模块导入报错:No module named ‘xxx’ 的解决方案
  • 数图信息科技亮相唐山社区零售论坛,数字化赋能行业高质量发展
  • LLM大模型 - 实战篇 - Assistant API 原理与实战应用
  • python微博舆情分析系统 情感分析 爬虫 机器学习 新浪微博 数据采集 大数据技术(源码)✅
  • FreeRTOS消息队列剖析讲解(思路+源码)
  • Trillium Engineering-无人机万向节有效负载 - 用于战术 UAS 的 EO 和 EO/IR 无人机相机万向节
  • 【Linux网络】Socket编程预备
  • pyAutoGUI 模块主要功能介绍-(4)消息框功能
  • 自学嵌入式第四十三天:硬件方面-ARM体系架构
  • PDF清晰度提升的幕后英雄:ImprovePdf
  • 《中国垒球规则》快投垒球局面规则·垒球5号位
  • Spring Boot 快速入门:构建企业级微服务架构
  • 【论文阅读】 WebDancer: Towards Autonomous Information Seeking Agency
  • MySQL集群运维
  • 未来浏览器:重新定义信息获取与交互
  • Mybatis-plus插件功能
  • weex分析美联储降息新周期:市场迎来机遇与挑战
  • Micronaut 集成 SPL 实现微服务
  • 类加载的过程以及双亲委派模型