一、C++与设计模式概述
各位好,我是这门课的主讲。今天咱们聊聊设计模式的起点——C++语言特性回顾、设计模式的定义与分类,还有UML类图基础。
说实话,我刚开始接触设计模式时,觉得这东西挺玄乎的。后来在项目中踩了不少坑,才慢慢体会到它的价值。嗯,咱们一步步来。
1.1 C++语言特性回顾
C++这门语言,说白了就是「带着镣铐跳舞」。它给了你极大的自由度,但也要求你对自己的每一行代码负责。
我个人习惯把C++的核心特性归纳为三类:
- 面向对象三大特性:封装、继承、多态。这是设计模式的基础土壤。
- 泛型编程:模板、STL容器与算法。很多模式可以用模板简化实现。
- 资源管理:RAII、智能指针。这是C++独有的优势,Java和C#学不来。
举个例子,多态是设计模式的灵魂。没有虚函数,策略模式、工厂模式这些根本玩不转。
// 一个简单的多态示例
class Shape {
public:
virtual void draw() const = 0; // 纯虚函数
virtual ~Shape() = default;
};
class Circle : public Shape {
public:
void draw() const override {
std::cout << "绘制圆形" << std::endl;
}
};
class Square : public Shape {
public:
void draw() const override {
std::cout << "绘制正方形" << std::endl;
}
};
// 客户端代码
void render(const Shape& shape) {
shape.draw(); // 多态调用
}
我在项目中遇到过一个问题:有人用C风格函数指针来实现策略模式,结果代码维护起来简直噩梦。后来改用虚函数+工厂模式,清爽多了。
小提示:C++11以后,
std::function和lambda表达式也可以替代部分设计模式。但别滥用,该用类层次结构时还是得用。
1.2 设计模式的定义与分类
设计模式是什么?说白了,就是「前人踩坑后总结出来的最佳实践」。它不是算法,不是框架,而是一种可复用的解决方案,用于解决特定场景下的设计问题。
GoF(Gang of Four,四人帮)把23种经典模式分为三大类:
| 分类 | 核心思想 | 代表模式 |
|---|---|---|
| 创建型 | 控制对象的创建过程 | 单例、工厂、建造者、原型 |
| 结构型 | 组合类与对象形成更大的结构 | 适配器、装饰器、代理、组合 |
| 行为型 | 管理对象间的交互与职责分配 | 策略、观察者、命令、迭代器 |
你想想看,为什么要有这些分类?
因为不同阶段关注的问题不同。创建型解决「对象怎么生出来」;结构型解决「对象怎么搭在一起」;行为型解决「对象之间怎么通信」。
核心观点:设计模式不是银弹。我曾经在一个项目里硬套了12个模式,结果代码比不用模式还复杂。记住:模式是工具,不是目标。
1.3 UML类图基础
UML类图,说白了就是「用图形把代码结构画出来」。我建议每个C++开发者都掌握它,因为画图的过程就是梳理设计的过程。
常用的类图关系有六种:
- 泛化(继承):空心三角形 + 实线,表示 is-a 关系
- 实现:空心三角形 + 虚线,表示接口实现
- 关联:普通箭头 + 实线,表示拥有关系
- 聚合:空心菱形 + 实线,表示整体-部分,部分可独立存在
- 组合:实心菱形 + 实线,表示整体-部分,部分不可独立
- 依赖:虚线箭头,表示临时使用关系
举个例子,一个文档编辑器:
// 组合关系:Document包含Paragraph
class Paragraph { /* ... */ };
class Document {
private:
std::vector<std::unique_ptr<Paragraph>> paragraphs; // 组合
public:
void addParagraph(std::unique_ptr<Paragraph> p) {
paragraphs.push_back(std::move(p));
}
};
嗯,这里要注意:组合和聚合的区别在于生命周期管理。组合中,部分随整体销毁;聚合中,部分可以独立存在。
避坑指南:我曾经在UML图上画了20多个类的关系,结果团队成员根本看不懂。后来我学乖了——每张图控制在7±2个类,只画关键关系。
下面我用一张SVG图来总结本章的知识体系:
这张图把本章的三个核心模块串起来了。C++语言特性是基础,设计模式是方法论,UML是沟通工具。三者缺一不可。
我的经验:刚开始学设计模式时,别急着背23种模式。先把C++的多态、模板、RAII搞扎实,再去看模式,你会发现很多东西都是「原来如此」。
好了,这一章就到这里。记住:设计模式不是背出来的,是用出来的。下一章咱们开始实战——单例模式,我会分享一个我在项目中用单例踩过的坑。