023 C++的设计模式(design pattern)


作者Lou Xiao, deepseek创建时间2025-04-02 16:47:06更新时间2025-04-02 16:47:06

一、设计模式基础

1.1 设计模式定义

  • 解决软件设计中常见问题的可复用方案
  • 介于编程范式和具体算法之间的中间层抽象
  • 提高代码可维护性、可扩展性和复用性

1.2 模式分类

类型关注点典型模式
创建型对象创建机制单例、工厂、建造者、原型
结构型对象组合方式适配器、装饰器、代理、组合
行为型对象间通信与职责分配观察者、策略、命令、状态

1.3 C++实现特点

  • 多范式语言特性(面向对象+模板元编程)
  • 资源管理(RAII模式)
  • 性能与灵活性的平衡
  • 现代C++特性应用(智能指针、lambda等)

二、创建型模式

2.1 单例模式(Singleton)

意图:保证类只有一个实例,并提供全局访问点

C++实现

1.双击鼠标左键复制此行;2.单击复制所有代码。
                                
                                    
1 class Singleton {
2 private:
3 static Singleton* instance;
4 Singleton() {} // 私有构造函数
5
6 public:
7 static Singleton* getInstance() {
8 if (!instance) {
9 // 双检查锁定(线程安全)
10 std::lock_guard<std::mutex> lock(mutex_);
11 if (!instance) {
12 instance = new Singleton();
13 }
14 }
15 return instance;
16 }
17
18 // 禁用拷贝和赋值
19 Singleton(const Singleton&) = delete;
20 void operator=(const Singleton&) = delete;
21 };

应用场景
- 配置管理器
- 日志系统
- 数据库连接池

注意事项
- 多线程安全
- 生命周期管理
- 测试困难(全局状态)

2.2 工厂方法模式

意图:定义创建对象的接口,但让子类决定实例化哪个类

UML结构

1.双击鼠标左键复制此行;2.单击复制所有代码。
                                
                                    
1 [Creator] <>-- [Product]
2 | |
3 [ConcreteCreator] --> [ConcreteProduct]

C++实现

1.双击鼠标左键复制此行;2.单击复制所有代码。
                                
                                    
1 class Button {
2 public:
3 virtual void render() = 0;
4 };
5
6 class WindowsButton : public Button { /*...*/ };
7 class MacButton : public Button { /*...*/ };
8
9 class Dialog {
10 public:
11 virtual Button* createButton() = 0;
12
13 void render() {
14 Button* btn = createButton();
15 btn->render();
16 }
17 };
18
19 class WindowsDialog : public Dialog {
20 Button* createButton() override {
21 return new WindowsButton();
22 }
23 };

优点
- 解耦产品创建和使用
- 符合开闭原则
- 支持依赖倒置

三、结构型模式

3.1 适配器模式

两种形式
1. 类适配器(多重继承)
2. 对象适配器(组合方式)

代码示例(对象适配器)

1.双击鼠标左键复制此行;2.单击复制所有代码。
                                
                                    
1 // 已有接口
2 class LegacyRectangle {
3 public:
4 void draw(int x1, int y1, int x2, int y2);
5 };
6
7 // 新接口
8 class Shape {
9 public:
10 virtual void draw(int x, int y, int w, int h) = 0;
11 };
12
13 class RectangleAdapter : public Shape {
14 LegacyRectangle adaptee;
15
16 public:
17 void draw(int x, int y, int w, int h) override {
18 adaptee.draw(x, y, x + w, y + h);
19 }
20 };

适用场景
- 集成遗留代码
- 接口不兼容的类协同工作
- 复用第三方库

四、行为型模式

4.1 观察者模式

组件
- Subject:维护观察者列表,状态变化时通知
- Observer:定义更新接口
- ConcreteSubject:存储具体状态
- ConcreteObserver:实现更新逻辑

现代C++实现

1.双击鼠标左键复制此行;2.单击复制所有代码。
                                
                                    
1 class Observer {
2 public:
3 virtual void update(const string& message) = 0;
4 };
5
6 class Subject {
7 vector<Observer*> observers;
8
9 public:
10 void attach(Observer* obs) {
11 observers.push_back(obs);
12 }
13
14 void notify(const string& msg) {
15 for (auto obs : observers) {
16 obs->update(msg);
17 }
18 }
19 };
20
21 // 使用lambda实现观察者
22 auto logger = [](const string& msg) {
23 cout << "Log: " << msg << endl;
24 };
25
26 subject.attach(&logger);

应用案例
- GUI事件处理
- 发布-订阅系统
- 数据监控系统

五、模式选择指南

5.1 决策树

  1. 需要控制对象创建?→ 创建型模式
  2. 需要组合对象或类?→ 结构型模式
  3. 需要管理算法或通信?→ 行为型模式

5.2 模式关系图

1.双击鼠标左键复制此行;2.单击复制所有代码。
                                
                                    
1 创建型 ← 组合 → 结构型
2 ↘ ↗ ↘
3 行为型 ← 职责分配

六、现代C++特性与模式

  1. 使用unique_ptr/shared_ptr管理对象生命周期
  2. 用移动语义优化工厂模式
  3. 模板方法模式与CRTP结合
  4. Lambda表达式实现命令模式
  5. Variant/Visit实现状态模式

七、反模式与注意事项

  1. 避免过度设计
  2. 防止模式嵌套过深
  3. 注意线程安全问题
  4. 考虑性能影响
  5. 不要强制匹配模式

附:各模式复杂度对比表
| 模式 | 实现难度 | 灵活性 | 可维护性 |
|------------|---------|--------|----------|
| 单例 | ★★☆ | ★☆☆ | ★★☆ |
| 装饰器 | ★★★ | ★★★ | ★★★ |
| 观察者 | ★★☆ | ★★★ | ★★★ |
| 访问者 | ★★★★ | ★★☆ | ★★☆ |

建议结合《设计模式:可复用面向对象软件的基础》和《Effective Modern C++》进行深入学习。

文章目录