design-pattern · diff
git:20260303.0dd7018 to git:20260305.a2f116c
43 added, 414 removed. Audit A to A.
---
name: design-pattern
- description: 精通软件设计模式,包括 GoF 模式、架构模式和现代设计原则。应用适当的模式提高代码的可维护性、可扩展性和可伸缩性。
+ description: 精通软件设计模式,包括 GoF 模式、架构模式和现代设计原则。应用适当的模式提高代码的可维护性、可扩展性和可伸缩性。使用此技能设计新软件组件、重构现有代码、审查代码设计质量、解决复杂设计问题,或需要 SOLID 原则和代码异味识别指导时使用。
---
# 设计模式精通
## 指令
你是软件设计模式方面的专家,具有深厚的知识:
- 四人帮(GoF)设计模式
- 架构模式(MVC、MVVM、Clean Architecture、Hexagonal Architecture)
- 现代模式(依赖注入、仓储模式、CQRS、事件溯源)
- 反模式和代码坏味道
- SOLID 原则和设计最佳实践
## 此技能的功能
该技能提供有关软件设计模式的全面知识和实践指导。它帮助你:
- 识别特定问题的适当模式
- 在各种编程语言中正确实现模式
- 识别代码坏味道和反模式
- 应用 SOLID 原则
- 平衡灵活性与简单性
- 重构代码以提高可维护性
## 何时使用此技能
在以下情况下使用此技能:
- 设计新的软件组件或系统
- 审查代码设计质量
- 重构现有代码
- 解决复杂的设计问题
- 解释设计决策
- 教授软件工程概念
- 识别代码坏味道并提出改进建议
## 核心能力
### 1. 创建型模式
- **单例模式(Singleton)**
- - 确保类只有一个实例
- - 提供全局访问点
- - 用于配置管理器、连接池、日志记录
-
- ```java
- public class DatabaseConnection {
- private static volatile DatabaseConnection instance;
- private DatabaseConnection() {}
-
- public static DatabaseConnection getInstance() {
- if (instance == null) {
- synchronized (DatabaseConnection.class) {
- if (instance == null) {
- instance = new DatabaseConnection();
- }
- }
- }
- return instance;
- }
- }
- ```
-
- **工厂方法模式(Factory Method)**
- - 定义创建对象的接口
- - 让子类决定实例化哪个类
- - 当确切类型直到运行时才知道时使用
-
- ```typescript
- interface Product {
- operation(): string;
- }
-
- abstract class Creator {
- abstract factoryMethod(): Product;
-
- someOperation(): string {
- const product = this.factoryMethod();
- return product.operation();
- }
- }
- ```
-
- **建造者模式(Builder)**
- - 逐步构建复杂对象
- - 将构造与表示分离
- - 用于具有许多可选参数的对象
-
- ```python
- class User:
- def __init__(self):
- self.name = None
- self.email = None
- self.age = None
-
- class UserBuilder:
- def __init__(self):
- self.user = User()
-
- def with_name(self, name):
- self.user.name = name
- return self
-
- def with_email(self, email):
- self.user.email = email
- return self
-
- def build(self):
- return self.user
- ```
-
- **原型模式(Prototype)**
- - 克隆现有对象而不耦合到它们的类
- - 当对象创建成本高时使用
-
- **抽象工厂模式(Abstract Factory)**
- - 提供创建相关对象族的接口
- - 当系统应独立于对象创建方式时使用
-
+ > 详见 [pattern-examples.md](./references/pattern-examples.md#创建型模式示例) 了解下列创建型模式的实现:
+ > - **单例模式**:确保类只有一个实例、提供全局访问点、用于配置管理器、连接池、日志记录
+ > - **工厂方法模式**:定义创建对象的接口、让子类决定实例化、正确的类型指定
+ > - **建造者模式**:逐步构建复杂对象、将构造与表示分策、適用于薩数不辨的对象
+ > - **原型模式**:克隆现有对象、当对象创建成本高时使用
+ > - **抽象工厂模式**:提供创建相关对象族的接口
### 2. 结构型模式
- **适配器模式(Adapter)**
- - 将类的接口转换为另一个接口
- - 允许不兼容的接口一起工作
-
- ```go
- type LegacyPrinter interface {
- PrintOld(text string)
- }
-
- type ModernPrinter interface {
- Print(text string)
- }
-
- type PrinterAdapter struct {
- legacy LegacyPrinter
- }
-
- func (a *PrinterAdapter) Print(text string) {
- a.legacy.PrintOld(text)
- }
- ```
-
- **装饰器模式(Decorator)**
- - 动态地为对象附加额外的职责
- - 提供灵活的子类化替代方案
-
- ```typescript
- interface Component {
- operation(): string;
- }
-
- class ConcreteComponent implements Component {
- operation(): string {
- return "ConcreteComponent";
- }
- }
-
- class Decorator implements Component {
- protected component: Component;
-
- constructor(component: Component) {
- this.component = component;
- }
-
- operation(): string {
- return this.component.operation();
- }
- }
-
- class ConcreteDecorator extends Decorator {
- operation(): string {
- return `ConcreteDecorator(${super.operation()})`;
- }
- }
- ```
-
- **外观模式(Facade)**
- - 为一组接口提供统一接口
- - 简化复杂子系统
-
- **代理模式(Proxy)**
- - 为另一个对象提供占位符
- - 控制访问、延迟初始化、日志记录
-
- **组合模式(Composite)**
- - 将对象组合成树形结构
- - 统一对待单个对象和组合
-
- **桥接模式(Bridge)**
- - 将抽象与实现解耦
- - 两者可以独立变化
-
- **享元模式(Flyweight)**
- - 在多个对象之间共享公共状态
- - 减少内存占用
-
+ > 详见 [pattern-examples.md](./references/pattern-examples.md#结构型模式示例) 了解下列结构型模式的实现:
+ > - **适配器模式**:将类的接口转换为另一个接口、允许不兼容的接口一起工作
+ > - **装饰器模式**:动态地为对象附加额外的职责、提供细挖的子类化替代方案
+ > - **外观模式**:为一组接口提供统一接口、简化复杂子系统
+ > - **代理模式**:为另一个对象提供占位符、控制访问、延迟初始化、日志记录
+ > - **组合模式**:将对象组合成树形结构、统一对待单个对象和组合
+ > - **桥接模式**:将抽象与实现解耦、两者可以独立变化
+ > - **享元模式**:在多个对象之间共享公共状态、减少内存占用
### 3. 行为型模式
- **策略模式(Strategy)**
- - 定义算法族
- - 使它们可互换
- - 当需要算法的不同变体时使用
-
- ```java
- interface PaymentStrategy {
- void pay(int amount);
- }
-
- class CreditCardStrategy implements PaymentStrategy {
- public void pay(int amount) {
- System.out.println("使用信用卡支付 " + amount);
- }
- }
-
- class PayPalStrategy implements PaymentStrategy {
- public void pay(int amount) {
- System.out.println("使用 PayPal 支付 " + amount);
- }
- }
-
- class ShoppingCart {
- private PaymentStrategy paymentStrategy;
-
- public void setPaymentStrategy(PaymentStrategy strategy) {
- this.paymentStrategy = strategy;
- }
-
- public void checkout(int amount) {
- paymentStrategy.pay(amount);
- }
- }
- ```
-
- **观察者模式(Observer)**
- - 定义一对多依赖关系
- - 当一个对象改变时,通知依赖者
- - 用于事件处理系统
-
- ```python
- class Subject:
- def __init__(self):
- self._observers = []
-
- def attach(self, observer):
- self._observers.append(observer)
-
- def notify(self, event):
- for observer in self._observers:
- observer.update(event)
-
- class Observer:
- def update(self, event):
- pass
- ```
-
- **命令模式(Command)**
- - 将请求封装为对象
- - 使用不同的请求参数化客户端
- - 支持撤销/重做操作
-
- **状态模式(State)**
- - 允许对象在内部状态改变时改变行为
- - 对象似乎改变了它的类
-
- **模板方法模式(Template Method)**
- - 在基类中定义算法骨架
- - 让子类覆盖特定步骤
-
- **迭代器模式(Iterator)**
- - 顺序访问聚合元素
- - 不暴露底层表示
-
- **中介者模式(Mediator)**
- - 定义封装对象交互方式的对象
- - 减少组件之间的耦合
-
- **备忘录模式(Memento)**
- - 捕获和外部化对象的内部状态
- - 允许以后恢复对象
-
- **责任链模式(Chain of Responsibility)**
- - 沿处理程序链传递请求
- - 每个处理程序决定处理或传递
-
- **访问者模式(Visitor)**
- - 将算法与对象结构分离
- - 在不修改对象的情况下添加新操作
+ > 详见 [pattern-examples.md](./references/pattern-examples.md#行为型模式示例) 了解下列行为型模式的实现:
+ > - **策略模式**:定义算法族、使它们可互换
+ > - **观察者模式**:定义一对多依赖、通知依赖者
+ > - **命令模式**:将请求封装为对象
+ > - **状态模式**:允许对象改变其行为
+ > - **模板方法模式**:在基类中定义算法骨架
+ > - **迭代器模式**:顺序访问聚合元素
+ > - **中介者模式**:定义封装对象交互方式的对象
+ > - **备忘录模式**:捕获和外部化对象内部状态
+ > - **责任链模式**:沿处理程序链传递请求
+ > - **访问者模式**:将算法与对象结构分离
### 4. 架构模式
- **模型-视图-控制器(MVC)**
- - 分离关注点:数据(Model)、展示(View)、逻辑(Controller)
- - 用于 Web 应用、桌面应用
-
- **模型-视图-视图模型(MVVM)**
- - 将 UI 与业务逻辑分离
- - 使用 View 和 ViewModel 之间的数据绑定
- - 在 WPF、Angular、Vue.js 中流行
-
- **整洁架构(Clean Architecture)**
- - 依赖规则:依赖指向内部
- - 实体 → 用例 → 接口适配器 → 框架
- - 独立于框架、UI、数据库
-
- **六边形架构(Ports and Adapters)**
- - 应用核心与外部关注点隔离
- - 端口定义接口,适配器实现它们
- - 易于测试、交换实现
-
- **仓储模式(Repository)**
- - 在领域和数据映射层之间调解
- - 为访问领域对象提供类似集合的接口
-
- ```typescript
- interface UserRepository {
- findById(id: string): Promise<User>;
- save(user: User): Promise<void>;
- delete(id: string): Promise<void>;
- }
-
- class UserRepositoryImpl implements UserRepository {
- async findById(id: string): Promise<User> {
- // 数据库访问逻辑
- }
-
- async save(user: User): Promise<void> {
- // 保存逻辑
- }
- }
- ```
-
- **CQRS(命令查询职责分离)**
- - 分离读写操作
- - 更新和查询使用不同的模型
- - 提高可扩展性和性能
-
- **事件溯源(Event Sourcing)**
- - 将状态存储为事件序列
- - 通过重放事件重建当前状态
- - 提供审计跟踪、时间旅行
+ > 详见 [pattern-examples.md](./references/pattern-examples.md#架构模式示例) 了解下列架构模式的实现:
+ > - **MVC**:分离关注点、用于 Web 应用、桌面应用
+ > - **MVVM**:将 UI 与业务逻辑分离、使用数据绑定
+ > - **整洁架构**:依赖规则、独立于框架、UI、数据库
+ > - **六边形架构**:应用核心与外部关注点隔离
+ > - **仓储模式**:在领域和数据映射层之间调解
+ > - **CQRS**:分离读写操作、提高可扩展性和性能
+ > - **事件溯源**:将状态存储为事件序列、提供审计跟踪
### 5. 现代模式
- **依赖注入(Dependency Injection)**
- - 控制反转原则
- - 从外部提供依赖项
- - 提高可测试性、灵活性
-
- ```java
- public class UserService {
- private final UserRepository repository;
-
- // 构造函数注入
- public UserService(UserRepository repository) {
- this.repository = repository;
- }
- }
- ```
-
- **服务定位器(Service Locator)**
- - 用于获取服务的中央注册表
- - 依赖注入的替代方案
-
- **空对象模式(Null Object)**
- - 提供默认对象而不是 null
- - 消除 null 检查
-
- ```python
- class User:
- def get_name(self):
- pass
-
- class RealUser(User):
- def __init__(self, name):
- self.name = name
-
- def get_name(self):
- return self.name
-
- class NullUser(User):
- def get_name(self):
- return "访客"
- ```
-
- **对象池模式(Object Pool)**
- - 重用创建成本高的对象
- - 管理可重用对象池
-
- **断路器模式(Circuit Breaker)**
- - 防止级联故障
- - 当服务不可用时快速失败
+ > 详见 [pattern-examples.md](./references/pattern-examples.md#现代模式示例) 了解下列现代模式的实现:
+ > - **依赖注入**:控制反转原则、从外部提供依赖项
+ > - **服务定位器**:用于获取服务的中央注册表
+ > - **空对象模式**:提供默认对象而不是 null
+ > - **对象池模式**:重用创建成本高的对象
+ > - **断路器模式**:防止级联故障、快速失败
## SOLID 原则
**单一职责原则(SRP)**
- 一个类应该只有一个改变的理由
- 每个类做好一件事
**开闭原则(OCP)**
- 对扩展开放,对修改关闭
- 使用抽象和多态
**里氏替换原则(LSP)**
- 子类型必须可替换其基类型
- 派生类不得破坏基类契约
**接口隔离原则(ISP)**
- 客户端不应依赖他们不使用的接口
- 创建特定接口而不是通用接口
**依赖倒置原则(DIP)**
- 依赖于抽象,而不是具体实现
- 高层模块不应依赖于低层模块
## 需要避免的反模式
**上帝对象(God Object)**
- 类知道太多或做太多
- 违反 SRP
**意大利面代码(Spaghetti Code)**
- 纠缠的控制流
- 难以理解和维护
**熔岩流(Lava Flow)**
- 永远不会删除的死代码
- 害怕破坏某些东西
**金锤子(Golden Hammer)**
- 过度使用一种模式
- "当你有锤子时,一切看起来都像钉子"
**过早优化(Premature Optimization)**
- 在识别瓶颈之前进行优化
- 使代码不必要地复杂
**货物崇拜编程(Cargo Cult Programming)**
- 在不理解原因的情况下使用模式
- 在没有理解的情况下复制代码
## 模式选择指南
**何时使用创建型模式:**
- 对象创建复杂
- 需要控制实例创建
- 想要将创建与使用解耦
**何时使用结构型模式:**
- 需要组合对象
- 想要适配接口
- 需要简化复杂系统
**何时使用行为型模式:**
- 需要定义对象之间的通信
- 想要封装算法
- 需要对象行为的灵活性
## 示例
- ### 示例 1: 重构为策略模式
-
- **之前:**
- ```java
- class PaymentProcessor {
- public void processPayment(String type, int amount) {
- if (type.equals("credit")) {
- // 信用卡逻辑
- } else if (type.equals("paypal")) {
- // PayPal 逻辑
- } else if (type.equals("crypto")) {
- // 加密货币逻辑
- }
- }
- }
- ```
-
- **之后:**
- ```java
- interface PaymentStrategy {
- void pay(int amount);
- }
-
- class PaymentProcessor {
- private PaymentStrategy strategy;
-
- public void setStrategy(PaymentStrategy strategy) {
- this.strategy = strategy;
- }
-
- public void processPayment(int amount) {
- strategy.pay(amount);
- }
- }
- ```
-
- ### 示例 2: 实现仓储模式
-
- ```typescript
- // 领域实体
- class User {
- constructor(
- public id: string,
- public name: string,
- public email: string
- ) {}
- }
-
- // 仓储接口
- interface UserRepository {
- findById(id: string): Promise<User | null>;
- findAll(): Promise<User[]>;
- save(user: User): Promise<void>;
- delete(id: string): Promise<void>;
- }
-
- // PostgreSQL 实现
- class PostgresUserRepository implements UserRepository {
- async findById(id: string): Promise<User | null> {
- const result = await db.query('SELECT * FROM users WHERE id = $1', [id]);
- return result.rows[0] ? new User(result.rows[0].id, result.rows[0].name, result.rows[0].email) : null;
- }
-
- async save(user: User): Promise<void> {
- await db.query(
- 'INSERT INTO users (id, name, email) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET name = $2, email = $3',
- [user.id, user.name, user.email]
- );
- }
- }
- ```
+ > 详见 [pattern-examples.md](./references/pattern-examples.md#实际示例) 了解下列实际实现示例:
+ > - **示例 1**:重构为策略模式(从条件语句到策略对象)
+ > - **示例 2**:实现仓储模式(领域实体、接口、具体实现)
## 最佳实践
- **首先理解问题** - 不要在不适合的地方强制使用模式。模式是解决反复出现问题的方案。
- **保持简单** - 从简单开始,根据需要添加模式。不要过度工程化。
- **清晰命名** - 适当时在类/方法名称中使用模式名称。使代码自文档化。
- **深思熟虑地组合模式** - 模式经常一起工作(工厂 + 单例、策略 + 模板方法等)
- **考虑权衡** - 模式增加复杂性。平衡灵活性与简单性。
- **测试驱动开发** - 先写测试。模式自然地从重构中出现。
- **重构到模式** - 不要预先设计模式。让它们随着代码的发展而出现。
## 代码审查清单
审查代码中模式使用时:
- [ ] 该模式是否适合问题?
- [ ] 实现是否正确?
- [ ] 它是否提高了代码质量?
- [ ] 它是否过度工程化?
- [ ] 是否遵循 SOLID 原则?
- [ ] 代码是否可测试?
- [ ] 文档是否完善?
- [ ] 是否有更简单的替代方案?
## 模式参考快速指南
| 问题 | 模式 | 何时使用 |
|------|------|----------|
| 需要单一实例 | 单例 | 全局状态、资源管理 |
| 复杂对象创建 | 建造者 | 许多可选参数 |
| 相关对象族 | 抽象工厂 | 需要一致的对象族 |
| 克隆现有对象 | 原型 | 对象创建成本高 |
| 接口不匹配 | 适配器 | 集成遗留代码 |
| 添加职责 | 装饰器 | 需要灵活的扩展 |
| 简化复杂系统 | 外观 | 需要简化接口 |
| 控制访问 | 代理 | 延迟加载、访问控制 |
| 可互换算法 | 策略 | 多个算法变体 |
| 通知依赖者 | 观察者 | 事件处理、发布-订阅 |
| 封装请求 | 命令 | 撤销/重做、排队操作 |
| 状态依赖行为 | 状态 | 复杂状态转换 |
## 备注
设计模式是软件设计中常见问题的经过验证的解决方案。使用它们来:
- 编写可维护、可扩展的代码
- 清晰地传达设计意图
- 利用软件社区的集体智慧
- 避免重新发明轮子
记住:**模式是工具,不是规则。** 使用判断力在特定上下文中适当地应用它们。最好的代码通常是有效解决问题的最简单的代码。