--- # Skills 自动引用配置 # AI 读取本文档时会自动加载以下规范文件,确保生成的代码符合项目规范 references: patterns: - path: skills/patterns/factory-pattern.yaml reason: "工厂模式 - 对象创建的统一管理" - path: skills/patterns/strategy-pattern.yaml reason: "策略模式 - 算法族的统一接口" - path: skills/patterns/template-method-pattern.yaml reason: "模板方法模式 - 算法骨架的固定结构" reference_modules: - path: skills/modules/pay/skill-pay.yaml reason: "支付模块 - 工厂+策略+模板方法模式组合案例" - path: skills/modules/ai/skill-ai.yaml reason: "AI 模块 - 工厂+策略模式案例" - path: skills/modules/infra/skill-infra.yaml reason: "基础设施模块 - 文件存储策略模式案例" usage_hint: "设计模式通常组合使用,参考 pay 模块的完整案例" --- # 设计模式应用场景提示词指南 > 本文档提供设计模式应用的标准化提示词模板,帮助开发者快速选择和应用合适的设计模式。 --- ## 目录 1. [设计模式选择指南](#1-设计模式选择指南) 2. [工厂模式应用提示词](#2-工厂模式应用提示词) 3. [策略模式应用提示词](#3-策略模式应用提示词) 4. [模板方法模式应用提示词](#4-模板方法模式应用提示词) 5. [实际案例分析](#5-实际案例分析) 6. [模式组合使用](#6-模式组合使用) --- ## 1. 设计模式选择指南 ### 1.1 场景-模式映射表 | 场景描述 | 推荐模式 | 项目案例 | |---------|---------|---------| | 需要根据配置动态创建不同类型的客户端 | 工厂模式 + 策略模式 | 支付渠道、短信渠道、文件存储 | | 需要统一处理流程,但具体实现不同 | 模板方法模式 | 支付下单流程、短信发送流程 | | 需要动态切换算法或行为 | 策略模式 | AI模型切换、支付方式切换 | | 需要隔离第三方SDK差异 | 策略模式 + 工厂模式 | 支付SDK、AI模型SDK | | 需要支持扩展新的产品类型 | 工厂模式 | 新增支付渠道、新增存储类型 | | 需要管理多个同类对象实例 | 工厂模式(带缓存) | PayClientFactory缓存客户端 | ### 1.2 选择决策树 ``` 需要解决的问题是什么? | +-- 创建对象 | | | +-- 创建逻辑复杂,需要封装 --> 工厂模式 | +-- 需要根据类型动态创建 --> 工厂模式 | +-- 需要缓存和复用实例 --> 工厂模式(带缓存) | +-- 行为变化 | | | +-- 需要动态切换算法 --> 策略模式 | +-- 有多种可互换的实现 --> 策略模式 | +-- 需要统一流程框架 --> 模板方法模式 | +-- 组合场景 | +-- 创建 + 行为变化 --> 工厂模式 + 策略模式 +-- 统一流程 + 具体实现不同 --> 工厂模式 + 模板方法模式 +-- 完整的多渠道系统 --> 工厂 + 策略 + 模板方法 ``` ### 1.3 模式特性对比 | 特性 | 工厂模式 | 策略模式 | 模板方法模式 | |-----|---------|---------|-------------| | 类型 | 创建型 | 行为型 | 行为型 | | 主要目的 | 封装对象创建 | 封装可互换算法 | 定义算法骨架 | | 开闭原则 | 支持 | 支持 | 支持 | | 扩展方式 | 新增工厂方法 | 新增策略类 | 新增子类 | | 客户端感知 | 不感知具体类 | 需选择策略 | 不感知实现细节 | | 适用场景 | 多类型创建 | 算法切换 | 流程标准化 | --- ## 2. 工厂模式应用提示词 ### 2.1 标准提示词模板 ```markdown ## 任务:使用工厂模式设计 [系统名称] ### 业务背景 [描述业务场景,例如:需要支持多种支付渠道,包括微信支付、支付宝、银联等] ### 设计要求 1. 创建抽象产品接口 - 定义 [产品名称] 接口 - 包含以下核心方法: - [方法1]:[功能描述] - [方法2]:[功能描述] 2. 创建具体产品实现 - 为每种类型创建实现类 - 实现类命名规范:[类型][产品]Impl(如 AlipayPayClient) 3. 创建工厂类 - 工厂命名:[产品]Factory(如 PayClientFactory) - 提供创建方法:create[产品](配置参数) - 考虑是否需要缓存实例 4. 注册机制 - 使用 Map 存储类型与实现类的映射 - 支持动态注册新类型 ### 参考实现 参考项目中 PayClientFactory 的实现模式。 ``` ### 2.2 工厂模式提示词示例:多渠道短信系统 ```markdown ## 任务:使用工厂模式设计短信客户端工厂 ### 业务背景 系统需要支持多种短信渠道:阿里云短信、腾讯云短信、华为云短信、七牛云短信。 不同渠道有不同的SDK和配置,但对外需要提供统一的发送接口。 ### 设计要求 #### Step 1: 创建短信客户端接口 ```java public interface SmsClient { Long getId(); void init(); SmsSendResultDTO sendSms(SmsSendMessageDTO message); SmsTemplateRespDTO getTemplate(String templateId); } ``` #### Step 2: 创建配置接口 ```java public interface SmsClientConfig { void validate(); } ``` #### Step 3: 创建抽象基类(可选,结合模板方法) ```java public abstract class AbstractSmsClient implements SmsClient { protected Long id; protected SmsClientConfig config; public AbstractSmsClient(Long id, SmsClientConfig config) { this.id = id; this.config = config; } @Override public final void init() { doInit(); } protected abstract void doInit(); } ``` #### Step 4: 创建具体实现 ```java // 阿里云短信客户端 public class AliyunSmsClient extends AbstractSmsClient { private IAcsClient client; @Override protected void doInit() { AliyunSmsClientConfig config = (AliyunSmsClientConfig) this.config; // 初始化阿里云SDK } @Override public SmsSendResultDTO sendSms(SmsSendMessageDTO message) { // 调用阿里云API } } // 腾讯云短信客户端 public class TencentSmsClient extends AbstractSmsClient { // 实现类似... } ``` #### Step 5: 创建工厂类 ```java @Component public class SmsClientFactoryImpl implements SmsClientFactory { // 缓存已创建的客户端 private final ConcurrentMap channelIdClients = new ConcurrentHashMap<>(); // 类型与客户端类映射 private static final Map> CLIENT_CLASS_MAP = Map.of( SmsChannelEnum.ALIYUN.getCode(), AliyunSmsClient.class, SmsChannelEnum.TENCENT.getCode(), TencentSmsClient.class, SmsChannelEnum.HUAWEI.getCode(), HuaweiSmsClient.class, SmsChannelEnum.QINIU.getCode(), QiniuSmsClient.class ); @Override public SmsClient createOrUpdateSmsClient(SmsChannelProperties properties) { AbstractSmsClient client = channelIdClients.get(properties.getId()); if (client == null) { client = createSmsClient(properties); client.init(); channelIdClients.put(client.getId(), client); } else { client.refresh(properties); } return client; } private AbstractSmsClient createSmsClient(SmsChannelProperties properties) { Class clientClass = CLIENT_CLASS_MAP.get(properties.getCode()); return ReflectUtil.newInstance(clientClass, properties.getId(), properties.getConfig()); } @Override public SmsClient getSmsClient(Long channelId) { return channelIdClients.get(channelId); } } ``` ### 预期产出 1. SmsClient 接口定义 2. AbstractSmsClient 抽象类 3. 4个具体实现类(Aliyun/Tencent/Huawei/Qiniu) 4. SmsClientFactory 工厂类 5. 各渠道配置类 ``` ### 2.3 扩展指南提示词 ```markdown ## 任务:在现有工厂中新增产品类型 ### 背景 需要在 [现有系统] 中新增支持 [新类型]。 ### 扩展步骤 1. **创建配置类** - 实现 [Config接口] - 定义新类型特有的配置字段 2. **创建实现类** - 继承 [抽象基类] - 实现所有抽象方法 3. **注册到工厂** - 在枚举中添加新类型 - 在工厂映射中添加对应关系 4. **添加测试** - 编写单元测试验证功能 ### 遵循原则 - 开闭原则:扩展开放,修改关闭 - 新增类型不应修改已有实现类 - 只需在工厂中添加映射关系 ``` --- ## 3. 策略模式应用提示词 ### 3.1 标准提示词模板 ```markdown ## 任务:使用策略模式设计 [功能名称] ### 业务背景 [描述需要支持多种算法/行为的场景] ### 设计要求 1. 定义策略接口 - 命名:[行为名称]Strategy 或直接作为核心接口 - 包含所有策略共有的方法 2. 实现具体策略 - 每种算法/行为一个实现类 - 实现类命名:[类型][行为名称]Strategy 3. 上下文使用 - 通过接口引用调用策略 - 可在运行时切换策略 4. 策略选择 - 结合工厂模式创建策略实例 - 根据配置/参数选择策略 ### 参考实现 参考项目中 PayClient 接口的多渠道实现。 ``` ### 3.2 策略模式提示词示例:多AI模型适配 ```markdown ## 任务:使用策略模式设计AI模型适配层 ### 业务背景 系统需要支持多种AI模型:OpenAI、Claude、百度文心一言、智谱AI、阿里通义千问等。 不同模型的API调用方式、参数格式不同,但对外需要提供统一的聊天、图像生成接口。 ### 设计要求 #### Step 1: 定义AI模型策略接口 ```java // Spring AI 已经提供了统一接口,我们基于此进行适配 public interface AiModelFactory { // 获取聊天模型 ChatModel getOrCreateChatModel(AiModelDO model); // 获取图像模型 ImageModel getOrCreateImageModel(AiModelDO model); // 获取向量模型 EmbeddingModel getOrCreateEmbeddingModel(AiModelDO model); } ``` #### Step 2: 实现具体策略(各平台适配) ```java @Service public class AiModelFactoryImpl implements AiModelFactory { // 使用缓存避免重复创建 private static final SingletonCache CHAT_MODEL_CACHE = new SingletonCache<>(); @Override public ChatModel getOrCreateChatModel(AiModelDO model) { String cacheKey = buildCacheKey(model); return CHAT_MODEL_CACHE.get(cacheKey, () -> doCreateChatModel(model)); } private ChatModel doCreateChatModel(AiModelDO model) { AiPlatformEnum platform = AiPlatformEnum.valueOf(model.getPlatform()); String apiKey = getApiKey(model.getKeyId()); String url = model.getUrl(); // 策略选择:根据平台类型创建不同的模型实例 return switch (platform) { case OPENAI -> buildOpenAIChatModel(apiKey, url); case ANTHROPIC -> buildAnthropicChatModel(apiKey, url); case YI_YAN -> buildYiYanChatModel(apiKey, url); case ZHI_PU -> buildZhiPuChatModel(apiKey, url); case TONG_YI -> buildTongYiChatModel(apiKey, url); case DEEP_SEEK -> buildDeepSeekChatModel(apiKey, url); case OLLAMA -> buildOllamaChatModel(url); default -> throw new IllegalArgumentException("Unknown platform: " + platform); }; } // 各平台具体创建方法 private ChatModel buildOpenAIChatModel(String apiKey, String url) { OpenAiApi api = OpenAiApi.builder() .apiKey(apiKey) .baseUrl(url) .build(); return OpenAIChatModel.builder() .openAiApi(api) .toolCallingManager(getToolCallingManager()) .build(); } private ChatModel buildZhiPuChatModel(String apiKey, String url) { ZhiPuApi api = new ZhiPuApi(apiKey); return new ZhiPuChatModel(api); } // 其他平台实现... } ``` #### Step 3: 定义平台枚举 ```java @Getter @AllArgsConstructor public enum AiPlatformEnum { // 国际平台 OPENAI("OpenAI", "OpenAI"), ANTHROPIC("Anthropic", "Anthropic Claude"), GEMINI("Gemini", "Google Gemini"), // 国内平台 YI_YAN("YiYan", "百度文心一言"), ZHI_PU("ZhiPu", "智谱AI"), TONG_YI("TongYi", "阿里通义千问"), DEEP_SEEK("DeepSeek", "DeepSeek"), MINI_MAX("MiniMax", "MiniMax"), // 本地部署 OLLAMA("Ollama", "Ollama 本地模型"); private final String platform; private final String name; } ``` #### Step 4: 服务层使用策略 ```java @Service public class AiChatMessageServiceImpl implements AiChatMessageService { @Resource private AiModelFactory aiModelFactory; @Resource private AiModelService modelService; @Override public Flux> sendChatMessageStream( AiChatMessageSendReqVO sendReqVO, Long userId) { // 1. 获取模型配置 AiModelDO model = modelService.getRequiredAiModel(sendReqVO.getModelId()); // 2. 通过工厂获取对应的策略实例(ChatModel) ChatModel chatModel = aiModelFactory.getOrCreateChatModel(model); // 3. 构建消息上下文 List messages = buildMessages(sendReqVO); // 4. 调用策略(统一接口,内部实现不同) return chatModel.stream(new Prompt(messages)) .map(response -> buildResponse(response)); } } ``` ### 设计优势 1. 统一接口:所有AI平台通过ChatModel统一调用 2. 易于扩展:新增平台只需添加枚举和创建方法 3. 缓存优化:使用Singleton缓存避免重复创建连接 4. 配置驱动:通过数据库配置切换模型 ### 预期产出 1. AiPlatformEnum 枚举定义 2. AiModelFactory 接口 3. AiModelFactoryImpl 实现类 4. 各平台ChatModel构建方法 ``` ### 3.3 策略模式扩展提示词 ```markdown ## 任务:在策略模式中新增策略 ### 背景 需要在现有 [策略系统] 中新增 [新策略类型]。 ### 扩展步骤 1. **确认策略接口方法** - 查看现有接口定义 - 确定需要实现的方法列表 2. **创建具体策略类** - 实现策略接口 - 处理特定于新策略的逻辑 3. **更新工厂/上下文** - 在枚举中添加新类型 - 在工厂中添加创建分支 4. **测试验证** - 编写单元测试 - 验证与现有策略的兼容性 ### 注意事项 - 保持接口一致性 - 处理策略特有的异常 - 考虑配置参数的差异 ``` --- ## 4. 模板方法模式应用提示词 ### 4.1 标准提示词模板 ```markdown ## 任务:使用模板方法模式设计 [流程名称] ### 业务背景 [描述需要统一流程但实现细节不同的场景] ### 设计要求 1. 创建抽象类 - 定义模板方法(final修饰) - 定义抽象方法(由子类实现) - 可定义钩子方法(可选实现) 2. 模板方法流程 - 步骤1:参数校验 - 步骤2:调用子类实现 - 步骤3:结果处理 - 步骤4:异常处理 3. 具体实现类 - 继承抽象类 - 实现所有抽象方法 ### 参考实现 参考项目中 AbstractPayClient 的实现模式。 ``` ### 4.2 模板方法模式提示词示例:支付客户端抽象 ```markdown ## 任务:使用模板方法模式设计支付客户端基类 ### 业务背景 系统支持多种支付渠道(微信、支付宝、钱包、模拟支付),每种渠道的下单流程相似: 参数校验 -> 调用第三方API -> 解析响应 -> 处理异常 但具体实现细节不同。 ### 设计要求 #### Step 1: 创建抽象基类 ```java @Slf4j public abstract class AbstractPayClient implements PayClient { protected Long channelId; protected String channelCode; protected Config config; public AbstractPayClient(Long channelId, String channelCode, Config config) { this.channelId = channelId; this.channelCode = channelCode; this.config = config; } // ==================== 模板方法 ==================== /** * 统一下单 - 模板方法 * 定义固定的执行流程,子类不能修改 */ @Override public final PayOrderRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO) { // 1. 参数校验 ValidationUtils.validate(reqDTO); // 2. 执行下单 try { return doUnifiedOrder(reqDTO); } catch (Throwable ex) { // 3. 统一异常处理 log.error("[unifiedOrder] 渠道[{}]下单异常", channelCode, ex); throw buildPayException(ex); } } /** * 统一退款 - 模板方法 */ @Override public final PayRefundRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO) { ValidationUtils.validate(reqDTO); try { return doUnifiedRefund(reqDTO); } catch (Throwable ex) { log.error("[unifiedRefund] 渠道[{}]退款异常", channelCode, ex); throw buildPayException(ex); } } // ==================== 抽象方法(子类必须实现) ==================== /** * 执行下单 - 由子类实现具体调用第三方API的逻辑 */ protected abstract PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Throwable; /** * 执行退款 - 由子类实现具体调用第三方API的逻辑 */ protected abstract PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable; /** * 初始化客户端 - 由子类实现SDK初始化 */ protected abstract void doInit(); /** * 解析支付回调 */ protected abstract PayOrderRespDTO doParseOrderNotify(PayNotifyDataDTO notifyData) throws Throwable; // ==================== 钩子方法(子类可选实现) ==================== /** * 刷新配置 - 默认实现,子类可覆盖 */ public void refresh(Config config) { this.config = config; doInit(); } // ==================== 工具方法 ==================== protected PayException buildPayException(Throwable ex) { if (ex instanceof PayException) { return (PayException) ex; } return new PayException(ex.getMessage(), ex); } } ``` #### Step 2: 创建具体实现 ```java // 支付宝支付客户端 public class AlipayQrPayClient extends AbstractPayClient { private AlipayClient client; public AlipayQrPayClient(Long channelId, AlipayPayClientConfig config) { super(channelId, PayChannelEnum.ALIPAY_QR.getCode(), config); } @Override protected void doInit() { AlipayPayClientConfig config = this.config; // 初始化支付宝SDK this.client = new DefaultAlipayClient( config.getServerUrl(), config.getAppId(), config.getPrivateKey(), config.getFormat(), config.getCharset(), config.getAlipayPublicKey(), config.getSignType() ); } @Override protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Throwable { // 1. 构建支付宝请求 AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest(); request.setBizContent(buildBizContent(reqDTO)); request.setNotifyUrl(reqDTO.getNotifyUrl()); // 2. 调用支付宝API AlipayTradePrecreateResponse response = client.execute(request); // 3. 解析响应 if (response.isSuccess()) { return PayOrderRespDTO.builder() .channelOrderNo(response.getOutTradeNo()) .qrCode(response.getQrCode()) .build(); } else { throw new PayException(response.getSubMsg()); } } @Override protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable { // 实现退款逻辑... } @Override protected PayOrderRespDTO doParseOrderNotify(PayNotifyDataDTO notifyData) throws Throwable { // 解析回调... } } // 微信支付客户端 public class WxNativePayClient extends AbstractPayClient { private WxPayService wxPayService; public WxNativePayClient(Long channelId, WxPayClientConfig config) { super(channelId, PayChannelEnum.WX_NATIVE.getCode(), config); } @Override protected void doInit() { WxPayClientConfig config = this.config; // 初始化微信支付SDK WxPayConfig wxConfig = new WxPayConfig(); wxConfig.setAppId(config.getAppId()); wxConfig.setMchId(config.getMchId()); wxConfig.setPrivateKeyPath(config.getPrivateKeyPath()); // ... this.wxPayService = new WxPayService(); this.wxPayService.setConfig(wxConfig); } @Override protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Throwable { // 使用WxJava SDK调用微信支付 WxPayNativeOrderResult result = wxPayService.createOrder( buildWxOrderRequest(reqDTO) ); return PayOrderRespDTO.builder() .qrCode(result.getCodeUrl()) .build(); } // 其他方法实现... } ``` ### 模板方法优势 1. **流程标准化**:所有渠道遵循统一的处理流程 2. **代码复用**:参数校验、异常处理等公共逻辑在基类实现 3. **易于维护**:修改公共逻辑只需修改基类 4. **扩展性强**:新增渠道只需继承基类实现抽象方法 ### 预期产出 1. AbstractPayClient 抽象基类 2. 各渠道具体实现类 3. 统一的异常处理机制 ``` ### 4.3 模板方法扩展提示词 ```markdown ## 任务:在模板方法模式中新增实现 ### 背景 需要在现有 [模板类] 的基础上新增 [新实现类型]。 ### 扩展步骤 1. **创建具体实现类** - 继承抽象基类 - 实现所有抽象方法 2. **初始化处理** - 在 doInit() 中初始化第三方SDK - 配置必要的认证信息 3. **实现核心方法** - doUnifiedXxx():调用第三方API - doParseXxxNotify():解析回调数据 4. **注册到工厂** - 在工厂中添加创建逻辑 - 在枚举中添加类型定义 ### 代码模板 ```java public class XxxPayClient extends AbstractPayClient { private XxxSdkClient client; // 第三方SDK客户端 public XxxPayClient(Long channelId, XxxPayClientConfig config) { super(channelId, PayChannelEnum.XXX.getCode(), config); } @Override protected void doInit() { // 初始化SDK客户端 this.client = new XxxSdkClient.Builder() .appId(config.getAppId()) .apiKey(config.getApiKey()) .build(); } @Override protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Throwable { // 调用第三方API XxxOrderRequest request = buildRequest(reqDTO); XxxOrderResponse response = client.createOrder(request); // 转换响应 return PayOrderRespDTO.builder() .channelOrderNo(response.getOrderId()) .build(); } // 实现其他抽象方法... } ``` ``` --- ## 5. 实际案例分析 ### 5.1 案例一:多渠道支付系统 #### 业务场景 系统需要支持微信支付、支付宝、钱包支付、模拟支付等多种支付渠道,每种渠道有不同的: - SDK接入方式 - 配置参数 - API调用方式 - 响应解析方式 #### 设计方案 **模式组合**:工厂模式 + 策略模式 + 模板方法模式 ``` ┌─────────────────────────────────────────────────────────────┐ │ PayClientFactory │ │ (工厂模式 - 创建客户端) │ │ │ │ getPayClient(channelId) ──> 缓存中获取或创建客户端实例 │ └──────────────────────┬──────────────────────────────────────┘ │ 创建 ▼ ┌─────────────────────────────────────────────────────────────┐ │ AbstractPayClient │ │ (模板方法模式 - 统一流程骨架) │ │ │ │ unifiedOrder() { │ │ validate(); // 参数校验 │ │ doUnifiedOrder(); // 调用子类实现 │ │ handleException(); // 异常处理 │ │ } │ └──────────────────────┬──────────────────────────────────────┘ │ 继承 ┌────────────┼────────────┬────────────┐ ▼ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ AlipayClient │ │ WxPayClient │ │WalletClient │ │ MockClient │ │ (支付宝) │ │ (微信) │ │ (钱包) │ │ (模拟) │ │ │ │ │ │ │ │ │ │ 策略模式实现 │ │ 策略模式实现 │ │ 策略模式实现 │ │ 策略模式实现 │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ ``` #### 关键代码 ```java // 策略接口(PayClient)- 定义统一行为 public interface PayClient { Long getId(); PayOrderRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO); PayRefundRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO); PayTransferRespDTO unifiedTransfer(PayTransferUnifiedReqDTO reqDTO); } // 模板方法(AbstractPayClient)- 定义流程骨架 public abstract class AbstractPayClient implements PayClient { @Override public final PayOrderRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO) { ValidationUtils.validate(reqDTO); try { return doUnifiedOrder(reqDTO); // 子类实现 } catch (Throwable ex) { throw buildPayException(ex); } } protected abstract PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Throwable; } // 工厂(PayClientFactory)- 创建和管理客户端 @Component public class PayClientFactoryImpl implements PayClientFactory { private final ConcurrentMap> clients = new ConcurrentHashMap<>(); private static final Map> CLIENT_CLASS_MAP = Map.of( "wx_pub", WxPubPayClient.class, "wx_native", WxNativePayClient.class, "alipay_wap", AlipayWapPayClient.class, "alipay_qr", AlipayQrPayClient.class, "wallet", WalletPayClient.class, "mock", MockPayClient.class ); @Override public PayClient getPayClient(Long channelId) { return clients.computeIfAbsent(channelId, this::createPayClient); } } ``` #### 扩展指南:新增银联支付 ```markdown ## 任务:新增银联支付渠道 ### 步骤 1. **创建配置类** ```java @Data public class UnionPayClientConfig implements PayClientConfig { private String merchantId; // 商户号 private String apiKey; // API密钥 private String certPath; // 证书路径 private String certPassword; // 证书密码 } ``` 2. **创建客户端类** ```java public class UnionPayQrPayClient extends AbstractPayClient { @Override protected void doInit() { // 初始化银联SDK } @Override protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Throwable { // 调用银联下单API } // 实现其他方法... } ``` 3. **注册到工厂** ```java CLIENT_CLASS_MAP.put("union_pay_qr", UnionPayQrPayClient.class); ``` 4. **添加枚举** ```java UNION_PAY_QR("union_pay_qr", "银联扫码支付"); ``` ``` --- ### 5.2 案例二:多存储类型文件系统 #### 业务场景 系统需要支持多种文件存储方式:本地存储、S3(MinIO/OSS/COS)、FTP、SFTP、数据库存储。不同存储方式的: - 配置参数不同 - 上传/下载/删除实现不同 - 访问URL生成方式不同 #### 设计方案 **模式组合**:策略模式 + 工厂模式 + 模板方法模式 ``` ┌─────────────────────────────────────────────────────────────┐ │ FileClientFactory │ │ (工厂模式 - 创建客户端) │ └──────────────────────┬──────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ AbstractFileClient │ │ (模板方法模式 - 统一流程) │ └──────────────────────┬──────────────────────────────────────┘ │ ┌────────────┼────────────┬────────────┬───────────┐ ▼ ▼ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐ ┌─────────────┐ │LocalFileClient│ │ S3FileClient │ │FtpFileClient│ │SftpFileClient│ │DBFileClient │ │ (本地) │ │ (S3/OSS) │ │ (FTP) │ │ (SFTP) │ │ (数据库) │ └──────────────┘ └──────────────┘ └──────────────┘ └─────────────┘ └─────────────┘ ``` #### 关键代码 ```java // 策略接口 public interface FileClient { Long getId(); void upload(byte[] content, String path, String type); byte[] getContent(String path); void delete(String path); String getPresignedUrl(String path, int timeout); } // 模板方法 public abstract class AbstractFileClient implements FileClient { protected Long id; protected Config config; public AbstractFileClient(Long id, Config config) { this.id = id; this.config = config; } public final void init() { doInit(); } protected abstract void doInit(); } // 枚举定义类型与类映射 @Getter @AllArgsConstructor public enum FileStorageEnum { LOCAL(10, LocalFileClientConfig.class, LocalFileClient.class), S3(20, S3FileClientConfig.class, S3FileClient.class), FTP(30, FtpFileClientConfig.class, FtpFileClient.class), SFTP(40, SftpFileClientConfig.class, SftpFileClient.class), DATABASE(50, NoneFileClientConfig.class, DBFileClient.class); private final Integer storage; private final Class configClass; private final Class clientClass; } ``` --- ### 5.3 案例三:多AI模型适配 #### 业务场景 系统需要支持多种AI平台:OpenAI、Claude、文心一言、智谱AI、通义千问、DeepSeek、Ollama本地部署等。不同平台: - API格式不同 - 认证方式不同 - 响应结构不同 #### 设计方案 **模式组合**:工厂模式 + 策略模式 ``` ┌─────────────────────────────────────────────────────────────┐ │ AiModelFactory │ │ (工厂模式 - 创建模型实例) │ │ │ │ getOrCreateChatModel(model) -> 缓存获取或创建 │ └──────────────────────┬──────────────────────────────────────┘ │ switch by platform ▼ ┌─────────────────────────────────────────────────────────────┐ │ ChatModel │ │ (Spring AI 统一接口 - 策略模式) │ │ │ │ call(Prompt) -> ChatResponse │ │ stream(Prompt) -> Flux │ └──────────────────────┬──────────────────────────────────────┘ │ 实现 ┌─────────────────┼─────────────────┬─────────────────┐ ▼ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │OpenAIChat │ │ZhiPuChat │ │DeepSeekChat │ │OllamaChat │ │ Model │ │ Model │ │ Model │ │ Model │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ ``` #### 关键代码 ```java // 工厂实现 @Service public class AiModelFactoryImpl implements AiModelFactory { @Override public ChatModel getOrCreateChatModel(AiModelDO model) { String cacheKey = buildCacheKey(model); return Singleton.get(cacheKey, () -> doCreateChatModel(model)); } private ChatModel doCreateChatModel(AiModelDO model) { AiPlatformEnum platform = AiPlatformEnum.valueOf(model.getPlatform()); return switch (platform) { case OPENAI -> buildOpenAIChatModel(model); case ANTHROPIC -> buildAnthropicChatModel(model); case ZHI_PU -> buildZhiPuChatModel(model); case DEEP_SEEK -> buildDeepSeekChatModel(model); case OLLAMA -> buildOllamaChatModel(model); // ... 其他平台 }; } } ``` --- ## 6. 模式组合使用 ### 6.1 三种模式的协作关系 ``` ┌────────────────────────────────────────────────────────────────┐ │ 业务场景 │ │ "需要支持多种XXX,统一调用方式" │ └────────────────────────────────────────────────────────────────┘ │ ▼ ┌────────────────────────────────────────────────────────────────┐ │ 工厂模式 │ │ │ │ 职责:创建具体实例 │ │ - 根据类型/配置创建对应的实现类实例 │ │ - 缓存已创建的实例 │ │ - 支持配置热刷新 │ │ │ │ 产出:Product 接口的实现类实例 │ └────────────────────────────────────────────────────────────────┘ │ ▼ ┌────────────────────────────────────────────────────────────────┐ │ 策略模式 │ │ │ │ 职责:定义统一行为接口 │ │ - 定义所有实现类共有的方法 │ │ - 不同实现类提供不同的算法/行为 │ │ - 运行时可切换 │ │ │ │ 产出:Product 接口定义 │ └────────────────────────────────────────────────────────────────┘ │ ▼ ┌────────────────────────────────────────────────────────────────┐ │ 模板方法模式 │ │ │ │ 职责:定义统一流程骨架 │ │ - 定义模板方法(final)控制执行流程 │ │ - 定义抽象方法由子类实现 │ │ - 复用公共逻辑(校验、异常处理、日志) │ │ │ │ 产出:AbstractProduct 抽象类 │ └────────────────────────────────────────────────────────────────┘ ``` ### 6.2 组合使用提示词模板 ```markdown ## 任务:使用设计模式组合设计 [系统名称] ### 业务场景 [描述业务需求,强调多类型支持、统一调用、流程标准化] ### 设计要求 #### 1. 策略层设计(定义行为) **创建策略接口** ```java public interface [Product] { // 核心业务方法 Result doSomething(Request request); } ``` #### 2. 模板层设计(定义流程) **创建抽象基类** ```java public abstract class Abstract[Product] implements [Product] { // 模板方法 @Override public final Result doSomething(Request request) { // 1. 参数校验 validate(request); // 2. 执行业务 try { return doDoSomething(request); } catch (Exception e) { // 3. 异常处理 return handleException(e); } } // 抽象方法 protected abstract Result doDoSomething(Request request); protected abstract void doInit(); } ``` #### 3. 工厂层设计(创建实例) **创建工厂接口和实现** ```java public interface [Product]Factory { [Product] get[Product](Long id); [Product] create[Product](Config config); } @Component public class [Product]FactoryImpl implements [Product]Factory { private final ConcurrentMap cache = new ConcurrentHashMap<>(); @Override public [Product] get[Product](Long id) { return cache.computeIfAbsent(id, this::create[Product]); } } ``` #### 4. 具体实现 **为每种类型创建实现类** ```java public class [Type][Product] extends Abstract[Product] { @Override protected void doInit() { // 初始化特定类型 } @Override protected Result doDoSomething(Request request) { // 实现特定逻辑 } } ``` ### 预期产出 1. [Product] 接口定义 2. Abstract[Product] 抽象类 3. [Product]Factory 工厂类 4. 多个具体实现类 5. 类型枚举定义 ``` ### 6.3 扩展新类型的标准流程 ```markdown ## 任务:在组合模式系统中扩展新类型 ### 扩展流程图 ``` ┌─────────────────┐ │ 1. 创建配置类 │ 实现 Config 接口,定义新类型配置字段 └────────┬────────┘ │ ▼ ┌─────────────────┐ │ 2. 创建实现类 │ 继承抽象基类,实现所有抽象方法 └────────┬────────┘ │ ▼ ┌─────────────────┐ │ 3. 添加枚举值 │ 在类型枚举中添加新类型定义 └────────┬────────┘ │ ▼ ┌─────────────────┐ │ 4. 注册到工厂 │ 在工厂的映射Map中添加类型-类关系 └────────┬────────┘ │ ▼ ┌─────────────────┐ │ 5. 编写测试 │ 验证新类型功能正确性 └─────────────────┘ ``` ### 扩展代码模板 ```java // Step 1: 配置类 @Data public class [NewType]Config implements Config { private String field1; private String field2; // ... } // Step 2: 实现类 public class [NewType][Product] extends Abstract[Product]<[NewType]Config> { public [NewType][Product](Long id, [NewType]Config config) { super(id, config); } @Override protected void doInit() { // 初始化逻辑 } @Override protected Result doDoSomething(Request request) { // 业务逻辑 } } // Step 3: 枚举 [NEW_TYPE](100, "[NewType]", "新类型描述"); // Step 4: 工厂注册 CLIENT_MAP.put(TypeEnum.NEW_TYPE, [NewType][Product].class); // Step 5: 测试 @Test void test[NewType]() { // ... } ``` ``` --- ## 附录:项目中的设计模式文件索引 ### 工厂模式实现位置 | 模块 | 工厂类 | 路径 | |-----|-------|------| | pay | PayClientFactoryImpl | yudao-module-pay/.../pay/core/client/impl/PayClientFactoryImpl.java | | infra | FileClientFactory | yudao-module-infra/.../file/core/client/FileClientFactory.java | | ai | AiModelFactoryImpl | yudao-module-ai/.../framework/ai/core/model/AiModelFactoryImpl.java | ### 策略模式实现位置 | 模块 | 策略接口 | 实现类 | |-----|---------|--------| | pay | PayClient | AlipayPayClient, WxPayClient, WalletPayClient, MockPayClient | | infra | FileClient | LocalFileClient, S3FileClient, FtpFileClient, DBFileClient | | ai | ChatModel (Spring AI) | OpenAIChatModel, ZhiPuChatModel, DeepSeekChatModel | ### 模板方法模式实现位置 | 模块 | 抽象类 | 路径 | |-----|-------|------| | pay | AbstractPayClient | yudao-module-pay/.../pay/core/client/impl/AbstractPayClient.java | | infra | AbstractFileClient | yudao-module-infra/.../file/core/client/AbstractFileClient.java | --- > 文档版本:1.0.0 > 更新日期:2026-03-18 > 维护者:Technical Writer Agent