【读书笔记】《C++ Software Design》第三章 The Purpose of Design Patterns

《C++ Software Design》第三章 The Purpose of Design Patterns


Design patterns serve as standardized solutions to recurring problems in software design. They provide a common vocabulary for developers and establish best practices that have been proven effective through years of practical experience.

Key purposes include:

  • Problem-Solving: They offer ready-made solutions to common design challenges (e.g., the Observer pattern for event handling systems or the Singleton pattern for resource management)
  • Communication Enhancement: Patterns create a shared language that simplifies team discussions (e.g., saying "we'll use a Factory here" conveys complex implementation concepts concisely)
  • Code Quality Improvement: By following established patterns, developers can avoid common pitfalls and produce more maintainable code
  • Architectural Consistency: Patterns help maintain uniform design approaches across large projects
  • Knowledge Transfer: They encapsulate decades of collective programming wisdom into reusable concepts

Common application scenarios:

  • Enterprise systems (using patterns like MVC for web applications)
  • Game development (employing patterns like State for character behavior)
  • Operating systems (utilizing patterns like Proxy for resource access control)

Example: The Strategy pattern allows switching between different algorithms at runtime, useful in payment processing systems where payment methods (credit card, PayPal, etc.) can be dynamically selected without changing client code.


Guideline 11: Understand the Purpose of Design Patterns

设计模式不仅仅是一段可复用的代码片段,更是一种沉淀了大量实践经验的沟通与设计手段。具体而言,它具备以下四个要素:

11.1 A Design Pattern Has a Name

  • 含义:模式名称是团队成员快速达成共识的"代号"。

  • 示例:提及"策略模式(Strategy)"时,即意味着"可变行为在运行时可被封装到策略对象中,并由客户端按需选择"。

  • 实践建议

    1. 在文档、UML 图、PR 描述中始终使用标准英文名称;
    2. 若团队自造名称,务必在知识库中给出对应规范名称的映射,避免歧义。

11.2 A Design Pattern Carries an Intent

  • 含义:每个模式都有一个简洁且明确的"意图(Intent)",回答"为什么要这么做"。

  • 示例

    • Observer:当一个对象状态变化时,需要自动通知所有依赖者并同步更新。
    • Factory Method:将对象创建逻辑从使用者中分离,使用者仅依赖抽象接口。
  • 实践要点

    1. 在设计评审前,先将模式意图写成一句话;
    2. 对照意图检查实现代码是否真正解决了该问题。

11.3 A Design Pattern Introduces an Abstraction

  • 含义:模式通过抽象接口(基类或概念)把"可变部分"和"固定部分"分离。

  • 示例(装饰者模式 Decorator)

    cpp 复制代码
    struct Component { virtual void operation() = 0; };
    class ConcreteComponent : public Component {
      void operation() override { /* 原始逻辑 */ }
    };
    class Decorator : public Component {
      std::unique_ptr<Component> wrappee_;
    public:
      Decorator(std::unique_ptr<Component> c)
        : wrappee_(std::move(c)) {}
      void operation() override {
        // 额外行为(前)
        wrappee_->operation();
        // 额外行为(后)
      }
    };
    • 抽象接口 Component 定义了通用契约,装饰者 Decorator 只需依赖该接口即可插入额外职责。

11.4 A Design Pattern Has Been Proven

  • 含义:模式来源于大量项目积累,已在社区和企业级系统中得到验证。

  • 案例证据

    • 大型金融系统中,使用工厂模式和依赖注入框架后,新增交易类型时的改动量平均减少 40%。
    • 某开源数据库通过策略模式替换存储引擎后,实现了无需重启的热切换功能。
  • 警示:不要盲目搬用------理解模式的适用场景和权衡,才能发挥其真正价值。


Guideline 12: Beware of Design Pattern Misconceptions

不要把"使用模式"当成项目目标,也不要陷入对实现细节或偏见的误区。

12.1 Design Patterns Are Not a Goal

  • 误区:为了"炫技"或"达标"而硬塞模式。
  • 真相:模式是解决特定问题的工具,若业务场景简单,直接函数或小型类划分即可,无需复杂模式。

12.2 Design Patterns Are Not About Implementation Details

  • 误区:关注 UML 静态类图,复制示例代码到项目中。
  • 真相:先要洞察设计意图,再结合 C++ 特性(继承、模板、lambda、constexpr)灵活实现。

12.3 Design Patterns Are Not Limited to OOP or Dynamic Polymorphism

  • 误区:以为所有模式都要靠虚函数和继承。

  • 真相

    • 编译时策略模式

      cpp 复制代码
      template<typename Strategy>
      class Context {
        Strategy strat_;
      public:
        auto execute(auto&&... args) {
          return strat_.doAlgorithm(std::forward<decltype(args)>(args)...);
        }
      };
    • 静态多态(CRTP 实现):如静态 Visitor 模式。


Guideline 13: Design Patterns Are Everywhere

良好的设计早已渗透于标准库和第三方库之中。学会识别并借鉴它们的实现,能快速提升自身设计能力。

  • Iterator 模式

    • std::vector<T>::iteratorstd::begin/std::end 即是典型迭代器。
  • Adapter 模式

    • std::istream_iterator 将流接口适配为迭代器。
  • Singleton 模式(谨慎使用):

    • 常见于日志、配置中心,但要留意线程安全和可测试性。

建议:在阅读 STL 源码或公司框架时,列出遇到的模式名称,并写成短文档,供团队分享。


Guideline 14: Use a Design Pattern's Name to Communicate Intent

  • 代码注释与文档

    cpp 复制代码
    // 使用桥接模式(Bridge)实现图形设备和渲染后端分离
    class Renderer; 
    class shape {
      Renderer& renderer_;
    public:
      shape(Renderer& r): renderer_(r) {}
      virtual void draw() = 0;
    };
  • PR 描述

    "本 PR 引入责任链模式(Chain of Responsibility),用于动态构造请求处理流水线"

  • 效果

    • 评审者一看模式名,即可快速了解设计意图;
    • 降低沟通成本,加强团队对设计架构的共识。
相关推荐
R-G-B1 小时前
【15】OpenCV C++实战篇——fitEllipse椭圆拟合、 Ellipse()画椭圆
c++·人工智能·opencv·fitellipse椭圆拟合·ellipse画椭圆·椭圆拟合·绘制椭圆
界面开发小八哥3 小时前
MFC扩展库BCGControlBar Pro v36.2:MSAA和CodedUI测试升级
c++·mfc·bcg·界面控件
极客BIM工作室6 小时前
C++ 限制类对象数量的技巧与实践
开发语言·javascript·c++
郝学胜-神的一滴7 小时前
Horse3D引擎研发笔记(四):在QtOpenGL下仿three.js,封装EBO绘制四边形
c++·3d·unity·游戏引擎·godot·图形渲染·虚幻
终焉代码8 小时前
【C++】STL二叉搜索树——map与set容器的基础结构
开发语言·数据结构·c++
源代码•宸8 小时前
深入浅出设计模式——行为型模式之观察者模式 Observer
开发语言·c++·经验分享·观察者模式·设计模式·raii
小马敲马9 小时前
[4.2-2] NCCL新版本的register如何实现的?
开发语言·c++·人工智能·算法·性能优化·nccl
soilovedogs10 小时前
百度之星2024初赛第二场 BD202411染色
c++·算法·百度之星
快起来别睡了10 小时前
前端设计模式:让代码更优雅的“万能钥匙”
前端·设计模式
啊阿狸不会拉杆10 小时前
《算法导论》第 15 章 - 动态规划
数据结构·c++·算法·排序算法·动态规划·代理模式