Menu
CoddyTech

设计模式入门

本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 90 课,共 104 课。

设计模式是经过验证、可重复使用的解决方案,用于解决软件设计中常见的问题。它们不是可以直接复制的代码,而是描述如何构建类和对象以优雅地解决特定挑战的模板或蓝图。

这个概念由“四人帮”(GoF)在他们 1994 年出版的书中推广开来。该书整理了 23 种基础模式。这些模式通常分为三类:

类别 用途 示例
创建型 对象创建机制 Singleton、Factory、Builder
结构型 类和对象的组合 Adapter、Decorator、Composite
行为型 对象交互和职责 Observer、Strategy、Command

为什么要学习设计模式?设计模式为开发者提供了共同的词汇,说“这里使用 Factory”就能立即传达一个复杂的想法。它们还能帮你避免重复造轮子,让代码更灵活、更易维护。

在 C++ 中,设计模式会利用你已经学过的面向对象编程特性:继承、多态、抽象类和模板。在接下来的几节课中,你将实现几种重要的设计模式,并了解每种模式适用于什么场景。

challenge icon

挑战

简单

让我们来构建一个简单的模式分类器,展示你对三种设计模式类别的理解。你将创建一个系统,输入模式名称后,判断它属于哪种类别:Creational、Structural 或 Behavioral,并简要说明该类别的用途。

你需要将代码分散到三个文件中:

  • PatternCategory.h:定义一个名为 PatternCategory 的抽象基类,用来表示一种设计模式类别。它应包含:
    • 一个纯虚方法 getName(),以字符串形式返回类别名称
    • 一个纯虚方法 getPurpose(),返回对该类别中模式用途的描述
    • 一个虚析构函数

    然后,创建三个继承自 PatternCategory 的派生类:

    • CreationalCategory:返回名称 "Creational",用途为 "Object creation mechanisms"
    • StructuralCategory:返回名称 "Structural",用途为 "Class and object composition"
    • BehavioralCategory:返回名称 "Behavioral",用途为 "Object interaction and responsibility"
  • PatternClassifier.h:创建一个 PatternClassifier 类,用来判断给定模式所属的类别。

    你的分类器应包含一个 classify 方法,接收模式名称(字符串),并返回指向相应 PatternCategory 的指针。使用智能指针(std::unique_ptr)管理内存。

    分类器应识别以下模式:

    • Creational:Singleton、Factory、Builder
    • Structural:Adapter、Decorator、Composite
    • Behavioral:Observer、Strategy、Command

    如果无法识别模式名称,则返回 nullptr。

  • main.cpp:读取一个输入,即设计模式的名称。

    创建一个 PatternClassifier,并用它对输入的模式进行分类。如果模式能够识别,则打印:

    [PatternName] is a [CategoryName] pattern
    Purpose: [CategoryPurpose]

    如果无法识别该模式,则打印:

    Unknown pattern: [PatternName]

例如,输入 Singleton 时:

Singleton is a Creational pattern
Purpose: Object creation mechanisms

输入 Observer 时:

Observer is a Behavioral pattern
Purpose: Object interaction and responsibility

输入 Proxy 时:

Unknown pattern: Proxy

这个挑战将巩固你对三种设计模式类别的理解,同时让你练习继承、多态和智能指针,这些概念你都已经掌握。多文件结构也体现了真实项目组织相关类的方式。

亲手试试

#include <iostream>
#include <string>
#include "PatternClassifier.h"

int main() {
    // 读取模式名称
    std::string patternName;
    std::cin >> patternName;
    
    // TODO:创建一个 PatternClassifier 实例
    
    // TODO:使用分类器对输入的模式进行分类
    
    // TODO:如果模式被识别,输出:
    // "[PatternName] is a [CategoryName] pattern"
    // "Purpose: [CategoryPurpose]"
    
    // TODO:如果模式未被识别(nullptr),输出:
    // "Unknown pattern: [PatternName]"
    
    return 0;
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: C++ 在线编译器