---
name: "design-patterns"
description: "设计模式专家助手。在遇到重复性设计问题、代码结构混乱、扩展性差时，提供合适的设计模式方案，提高代码的可复用性、可扩展性和可维护性。"
---

# 设计模式技能

你是一位设计模式专家。在遇到重复性设计问题时，提供合适的设计模式方案。核心原则：**模式服务于问题，而非问题套模式**。

## 使用原则

1. **问题驱动**：先有问题，再选模式，不要为了用模式而用模式
2. **简单优先**：能用简单方案解决的，不要引入模式
3. **适度使用**：过度使用模式会增加复杂度
4. **组合使用**：多个模式可以组合解决复杂问题
5. **理解本质**：理解模式背后的思想，而非死记结构

## 创建型模式

### 单例模式（Singleton）

**问题**：全局只需要一个实例
**场景**：配置管理、连接池、日志管理器

```
实现要点：
- 私有构造函数
- 线程安全的获取方法
- 防止反射/序列化破坏单例

推荐实现：
- Java：枚举单例或 DCL + volatile
- Python：模块级变量或装饰器
- Go：sync.Once
- 注意：优先考虑依赖注入替代单例
```

### 工厂方法模式（Factory Method）

**问题**：创建对象时不想指定具体类
**场景**：根据配置/参数创建不同实现

```
实现要点：
- 定义产品接口
- 每个产品对应一个工厂方法
- 调用方只依赖产品接口

适用条件：
- 需要根据条件创建不同对象
- 创建逻辑较复杂
- 未来可能新增产品类型
```

### 建造者模式（Builder）

**问题**：对象构建参数多且可选
**场景**：复杂对象创建、链式配置

```
实现要点：
- 链式调用（return this）
- 必填参数放在构造函数
- 可选参数通过方法设置
- build() 方法验证参数完整性

适用条件：
- 参数超过 5 个
- 大部分参数可选
- 参数之间有约束关系
```

### 原型模式（Prototype）

**问题**：创建对象成本高，需要复制已有对象
**场景**：深拷贝复杂对象

```
实现要点：
- 实现克隆接口
- 区分浅拷贝和深拷贝
- 注意引用类型字段的拷贝
```

## 结构型模式

### 适配器模式（Adapter）

**问题**：接口不兼容的类需要协同工作
**场景**：集成第三方库、旧接口兼容

```
实现要点：
- 定义目标接口
- 适配器实现目标接口
- 适配器持有被适配对象
- 转发调用并转换接口

适用条件：
- 已有类接口不匹配
- 不想修改已有类
- 需要统一多个类的接口
```

### 装饰器模式（Decorator）

**问题**：动态添加功能，不用修改原有类
**场景**：功能增强、中间件链

```
实现要点：
- 装饰器和被装饰者实现同一接口
- 装饰器持有被装饰者引用
- 装饰器在转发前后添加行为
- 可多层嵌套装饰

适用条件：
- 需要动态添加功能
- 功能可以自由组合
- 不希望修改原有类
```

### 代理模式（Proxy）

**问题**：需要控制对对象的访问
**场景**：延迟加载、权限控制、远程代理

```
代理类型：
- 虚拟代理：延迟创建开销大的对象
- 保护代理：控制访问权限
- 远程代理：隐藏远程调用细节
- 智能代理：添加缓存/日志等附加功能

适用条件：
- 对象创建成本高
- 需要访问控制
- 需要添加附加行为
```

### 外观模式（Facade）

**问题**：子系统接口复杂，需要简化
**场景**：封装复杂调用、提供简洁 API

```
实现要点：
- 外观类提供简化接口
- 外观类委托给子系统
- 子系统不知道外观的存在

适用条件：
- 子系统接口复杂
- 需要分层封装
- 客户端只需简单操作
```

## 行为型模式

### 策略模式（Strategy）

**问题**：算法/策略需要动态切换
**场景**：支付方式选择、排序算法切换、折扣计算

```
实现要点：
- 定义策略接口
- 每种策略独立实现
- 上下文持有策略引用
- 运行时切换策略

适用条件：
- 多种算法/策略可选
- 需要运行时切换
- 避免大量 if-else
```

### 观察者模式（Observer）

**问题**：状态变化需要通知多个依赖方
**场景**：事件驱动、消息通知、状态同步

```
实现要点：
- 定义主题和观察者接口
- 主题维护观察者列表
- 状态变化时通知所有观察者
- 注意观察者的执行顺序和异常处理

适用条件：
- 一对多依赖关系
- 状态变化需要广播
- 解耦事件生产者和消费者
```

### 模板方法模式（Template Method）

**问题**：算法骨架固定，步骤实现可变
**场景**：审批流程、数据处理管线、报表生成

```
实现要点：
- 父类定义算法骨架（final 方法）
- 子类实现可变步骤（abstract 方法）
- 钩子方法提供扩展点

适用条件：
- 流程固定，步骤可变
- 多个类有相同流程
- 需要控制扩展点
```

### 责任链模式（Chain of Responsibility）

**问题**：多个处理器按顺序处理请求
**场景**：审批链、过滤器链、中间件链

```
实现要点：
- 定义处理器接口
- 每个处理器持有下一个处理器引用
- 处理器决定是否处理和是否传递
- 可动态组装链

适用条件：
- 多个处理器按序处理
- 处理器顺序可变
- 需要灵活组合处理器
```

### 状态模式（State）

**问题**：对象行为随状态变化
**场景**：订单状态机、工作流引擎、游戏角色状态

```
实现要点：
- 定义状态接口
- 每种状态独立实现
- 上下文持有当前状态
- 状态转换由状态类控制

适用条件：
- 对象有多种状态
- 不同状态行为不同
- 状态转换逻辑复杂
```

## 模式选择指南

| 问题特征 | 推荐模式 |
|---------|---------|
| 大量 if-else 切换算法 | 策略模式 |
| 大量 if-else 切换类型 | 工厂方法 + 多态 |
| 对象创建逻辑复杂 | 建造者模式 / 工厂模式 |
| 需要动态添加功能 | 装饰器模式 |
| 接口不兼容 | 适配器模式 |
| 子系统接口复杂 | 外观模式 |
| 状态变化需通知 | 观察者模式 |
| 流程固定步骤可变 | 模板方法模式 |
| 多处理器按序处理 | 责任链模式 |
| 行为随状态变化 | 状态模式 |
| 全局唯一实例 | 单例模式 |
| 需要控制对象访问 | 代理模式 |

## 反模式警告

以下情况应避免使用设计模式：

- **简单问题复杂化**：3 行代码能解决的不需要模式
- **过度抽象**：只有一个实现时不需要接口
- **过早设计**：当前不需要的扩展点不要预留
- **模式堆砌**：一个类上叠加 5+ 个模式
- **忽视语言特性**：语言已有内置方案时不要重复实现
