口诀
控制访问用代理 ,接口不兼容用适配 ,抽象实现分桥接 ,动态功能用装饰 ,统一接口用外观 ,大量对象用享元 ,树形结构用组合。
结构型设计模式对比表
| 模式 | 核心用途 | 适用场景 | 关键特点 | C++最佳实现 |
|---|---|---|---|---|
| 代理 | 控制对象访问 | 延迟加载/权限控制 | 不修改原对象 | std::shared_ptr 管理代理对象 |
| 适配器 | 接口转换 | 第三方库集成 | 接口不兼容转换 | 适配器 std::shared_ptr 持有被适配者 |
| 桥接 | 分离抽象与实现 | 多维度变化(如形状+绘制方式) | 避免类爆炸 | 用组合代替继承,std::shared_ptr 桥接 |
| 装饰 | 动态添加功能 | 日志/权限等扩展 | 比继承更灵活 | 装饰器继承组件接口并持有组件对象 |
| 外观 | 简化复杂系统 | 多子系统整合 | 统一高层接口 | 统一接口,外观类管理多子系统 |
| 享元 | 对象复用 | 大量相似对象(字符/像素) | 减少内存占用 | 工厂管理共享对象,std::map 实现 |
| 组合 | 树形结构统一处理 | 文件系统/组织架构 | 叶子/组合统一调用 | std::vectorstd::shared_ptr 存储子组件 |
结构型设计模式全解析
1. 代理模式 (Proxy)
关键点
- 为对象提供代理以控制访问
- 代理与真实对象实现相同接口
- 用于权限控制、延迟初始化、日志记录等
优缺点
| 优点 | 缺点 |
|---|---|
| 增加功能而不修改真实对象 | 代理可能增加性能开销 |
| 客户端与真实对象解耦 | 增加系统复杂度 |
| 便于实现权限控制和延迟加载 |
C++最佳实现(详细类解释)
cpp
// 抽象对象:定义客户端和真实对象的接口
class Subject {
public:
virtual void request() = 0; // 纯虚函数,定义请求接口
virtual ~Subject() = default; // 虚析构函数,确保正确销毁
};
// 真实对象:实现具体业务逻辑
class RealSubject : public Subject {
public:
void request() override {
std::cout << "RealSubject: Handling request.\n";
}
};
// 代理类:控制对真实对象的访问
class Proxy : public Subject {
private:
std::shared_ptr<RealSubject> realSubject; // 持有真实对象的智能指针
public:
Proxy() : realSubject(nullptr) {} // 初始化为nullptr
void request() override {
// 延迟初始化:首次调用时创建真实对象
if (!realSubject) {
realSubject = std::make_shared<RealSubject>();
}
std::cout << "Proxy: Checking access prior to firing real request.\n";
realSubject->request(); // 调用真实对象的方法
}
};
调用方式
cpp
auto subject = std::make_shared<Proxy>();
subject->request(); // 通过代理调用,实际执行真实对象方法
类图关系(UML标准表示)
has a <<interface>> Subject +request() RealSubject +request() Proxy +request()
2. 适配器模式 (Adapter)
关键点
- 将不兼容接口转换为客户端期望的接口
- 通过组合实现,避免继承导致的类爆炸
- 适用于集成已有类库
优缺点
| 优点 | 缺点 |
|---|---|
| 无需修改现有代码 | 适配器可能包含业务逻辑 |
| 使不兼容接口协同工作 | 增加系统复杂度 |
| 适合已有类库的集成 |
C++最佳实现(对象适配器)
cpp
// 目标接口:客户端期望的接口
class Target {
public:
virtual void request() = 0;
virtual ~Target() = default;
};
// 被适配者:已有类,接口不兼容
class Adaptee {
public:
void specificRequest() {
std::cout << "Adaptee: Specific request.\n";
}
};
// 适配器:实现目标接口,适配被适配者
class Adapter : public Target {
private:
std::shared_ptr<Adaptee> adaptee; // 持有被适配者对象
public:
Adapter(std::shared_ptr<Adaptee> adaptee) : adaptee(adaptee) {}
void request() override {
adaptee->specificRequest(); // 调用被适配者的方法
}
};
调用方式
cpp
auto adaptee = std::make_shared<Adaptee>();
auto adapter = std::make_shared<Adapter>(adaptee);
adapter->request(); // 通过适配器转换调用
类图关系(UML标准表示)
has a <<interface>> Target +request() Adaptee +specificRequest() Adapter +request()
3. 桥接模式 (Bridge)
关键点
- 将抽象与实现分离,使它们可以独立变化
- 用组合代替继承,避免"形状×绘制方式"类爆炸
- 两个独立变化的维度:抽象(Shape)和实现(DrawingAPI)
优缺点
| 优点 | 缺点 |
|---|---|
| 抽象与实现解耦,独立变化 | 增加系统复杂度 |
| 避免类爆炸(组合爆炸) | 需要额外接口设计 |
| 适合多维度变化的场景 |
C++最佳实现(详细类解释)
简单点儿说,将一个维度作为成员变量。
cpp
// 实现接口:定义实现部分的接口
class DrawingAPI {
public:
virtual void drawCircle(double x, double y, double radius) = 0;
virtual ~DrawingAPI() = default;
};
// 具体实现1:矢量绘制
class VectorDrawingAPI : public DrawingAPI {
public:
void drawCircle(double x, double y, double radius) override {
std::cout << "VectorAPI: Drawing circle at (" << x << ", " << y
<< ") with radius " << radius << "\n";
}
};
// 具体实现2:位图绘制
class BitmapDrawingAPI : public DrawingAPI {
public:
void drawCircle(double x, double y, double radius) override {
std::cout << "BitmapAPI: Drawing circle at (" << x << ", " << y
<< ") with radius " << radius << "\n";
}
};
// 抽象类:定义抽象部分的接口
class Shape {
protected:
std::shared_ptr<DrawingAPI> drawingAPI; // 持有实现对象
public:
Shape(std::shared_ptr<DrawingAPI> api) : drawingAPI(api) {}
virtual void draw() = 0; // 抽象方法
virtual ~Shape() = default;
};
// 扩展抽象:圆形
class CircleShape : public Shape {
private:
double x, y, radius;
public:
CircleShape(double x, double y, double radius, std::shared_ptr<DrawingAPI> api)
: Shape(api), x(x), y(y), radius(radius) {}
void draw() override {
drawingAPI->drawCircle(x, y, radius); // 调用实现接口
}
};
// 扩展抽象:方形
class SquareShape : public Shape {
private:
double x, y, side;
public:
SquareShape(double x, double y, double side, std::shared_ptr<DrawingAPI> api)
: Shape(api), x(x), y(y), side(side) {}
void draw() override {
std::cout << "SquareShape: Drawing square at (" << x << ", " << y
<< ") with side " << side << " using ";
drawingAPI->drawCircle(0, 0, 0); // 通过API模拟绘制
}
};
调用方式
cpp
auto vectorAPI = std::make_shared<VectorDrawingAPI>();
auto bitmapAPI = std::make_shared<BitmapDrawingAPI>();
auto circleVector = std::make_shared<CircleShape>(1.0, 2.0, 3.0, vectorAPI);
auto circleBitmap = std::make_shared<CircleShape>(1.0, 2.0, 3.0, bitmapAPI);
auto squareVector = std::make_shared<SquareShape>(5.0, 6.0, 4.0, vectorAPI);
circleVector->draw(); // 使用矢量API绘制圆形
circleBitmap->draw(); // 使用位图API绘制圆形
squareVector->draw(); // 使用矢量API绘制方形
类图关系(UML标准表示)
implements <<interface>> DrawingAPI +drawCircle(x, y, radius) VectorDrawingAPI +drawCircle(x, y, radius) BitmapDrawingAPI +drawCircle(x, y, radius) <<abstract>> Shape -drawingAPI: DrawingAPI +draw() CircleShape +draw() SquareShape +draw()
4. 装饰模式 (Decorator)
关键点
- 动态地给对象添加额外职责
- 通过组合实现,避免继承导致的类爆炸
- 装饰类与被装饰类实现相同接口
优缺点
| 优点 | 缺点 |
|---|---|
| 灵活性高,可动态添加功能 | 可能导致设计过于复杂 |
| 避免类爆炸(继承方式) | 对象数量增加 |
| 可组合多个装饰 |
C++最佳实现(详细类解释)
简单点儿说,装饰器基类继承组件并持有组件对象,装饰器子类添加额外功能。
cpp
// 组件接口:定义基本接口
class Component {
public:
virtual void operation() = 0;
virtual ~Component() = default;
};
// 具体组件:实现基本功能
class ConcreteComponent : public Component {
public:
void operation() override {
std::cout << "ConcreteComponent: Basic operation.\n";
}
};
// 装饰器基类:继承组件接口,持有一个组件对象
class Decorator : public Component {
protected:
std::shared_ptr<Component> component; // 持有被装饰对象
public:
Decorator(std::shared_ptr<Component> comp) : component(comp) {}
void operation() override {
component->operation(); // 调用被装饰对象的基本操作
}
};
// 具体装饰器1:添加额外功能
class ConcreteDecoratorA : public Decorator {
public:
ConcreteDecoratorA(std::shared_ptr<Component> comp) : Decorator(comp) {}
void operation() override {
Decorator::operation(); // 先调用基础操作
addedBehavior(); // 添加额外行为
}
void addedBehavior() {
std::cout << "ConcreteDecoratorA: Added behavior.\n";
}
};
// 具体装饰器2:添加另一额外功能
class ConcreteDecoratorB : public Decorator {
public:
ConcreteDecoratorB(std::shared_ptr<Component> comp) : Decorator(comp) {}
void operation() override {
Decorator::operation();
addedBehavior();
}
void addedBehavior() {
std::cout << "ConcreteDecoratorB: Added behavior.\n";
}
};
调用方式
cpp
auto component = std::make_shared<ConcreteComponent>();
auto decoratorA = std::make_shared<ConcreteDecoratorA>(component);
auto decoratorB = std::make_shared<ConcreteDecoratorB>(decoratorA);
decoratorB->operation(); // 依次执行:Basic → A → B
类图关系(UML标准表示)
has a <<interface>> Component +operation() ConcreteComponent +operation() Decorator +operation() ConcreteDecoratorA +addedBehavior() +operation() ConcreteDecoratorB +addedBehavior() +operation()
5. 外观模式 (Facade)
关键点
- 为复杂子系统提供统一接口
- 客户端通过外观类与子系统交互
- 屏蔽子系统的复杂性
优缺点
| 优点 | 缺点 |
|---|---|
| 简化接口,降低使用难度 | 增加额外外观类 |
| 降低客户端与子系统的耦合 | 可能隐藏子系统细节 |
| 适合复杂子系统 |
C++最佳实现(详细类解释)
cpp
// 子系统1
class Subsystem1 {
public:
void operation1() {
std::cout << "Subsystem1: Operation1.\n";
}
};
// 子系统2
class Subsystem2 {
public:
void operation2() {
std::cout << "Subsystem2: Operation2.\n";
}
};
// 外观类:提供统一接口
class Facade {
private:
std::shared_ptr<Subsystem1> subsystem1;
std::shared_ptr<Subsystem2> subsystem2;
public:
Facade() : subsystem1(std::make_shared<Subsystem1>()),
subsystem2(std::make_shared<Subsystem2>()) {}
void operation() {
subsystem1->operation1(); // 调用子系统1
subsystem2->operation2(); // 调用子系统2
}
};
调用方式
cpp
auto facade = std::make_shared<Facade>();
facade->operation(); // 通过外观简化调用
类图关系(UML标准表示)
uses uses Facade +operation() Subsystem1 +operation1() Subsystem2 +operation2()
6. 享元模式 (Flyweight)
关键点
- 通过共享技术支持大量细粒度对象
- 分离内部状态(共享)和外部状态(不共享)
- 减少内存消耗
优缺点
| 优点 | 缺点 |
|---|---|
| 减少内存使用 | 实现复杂 |
| 适合大量相似对象,提高性能 | 需要管理共享对象 |
C++最佳实现(详细类解释)
cpp
// 享元接口
class Flyweight {
public:
virtual void operation(std::string extrinsicState) = 0;
virtual ~Flyweight() = default;
};
// 具体享元:实现共享状态
class ConcreteFlyweight : public Flyweight {
public:
void operation(std::string extrinsicState) override {
std::cout << "ConcreteFlyweight: " << extrinsicState << "\n";
}
};
// 享元工厂:管理共享对象
class FlyweightFactory {
private:
std::map<std::string, std::shared_ptr<Flyweight>> flyweights;
public:
std::shared_ptr<Flyweight> getFlyweight(std::string key) {
if (flyweights.find(key) == flyweights.end()) {
flyweights[key] = std::make_shared<ConcreteFlyweight>();
}
return flyweights[key];
}
};
调用方式
cpp
auto factory = std::make_shared<FlyweightFactory>();
auto flyweight1 = factory->getFlyweight("key1");
auto flyweight2 = factory->getFlyweight("key2");
flyweight1->operation("State1"); // 共享对象,外部状态不同
flyweight2->operation("State2");
类图关系(UML标准表示)
creates <<interface>> Flyweight +operation(extrinsicState) ConcreteFlyweight +operation(extrinsicState) FlyweightFactory +getFlyweight(key)
7. 组合模式 (Composite)
关键点
- 将对象组合成树形结构表示"部分-整体"层次
- 客户端统一处理单个对象和组合对象
- 使客户端无需区分处理的是叶子还是组合
优缺点
| 优点 | 缺点 |
|---|---|
| 统一处理个体与组合 | 增加系统复杂度 |
| 适合树形结构,简化客户端代码 | 需要定义组合结构 |
C++最佳实现(详细类解释)
父节点跟子节点属性是一样的,所以都继承于Component,这里父节点添加额外成员children。
cpp
// 组件接口
class Component {
public:
virtual void add(std::shared_ptr<Component> component) = 0;
virtual void remove(std::shared_ptr<Component> component) = 0;
virtual void operation() = 0;
virtual ~Component() = default;
};
// 叶子节点:没有子节点
class Leaf : public Component {
public:
void add(std::shared_ptr<Component>) override {} // 无子节点,不实现
void remove(std::shared_ptr<Component>) override {} // 无子节点,不实现
void operation() override {
std::cout << "Leaf: Operation.\n";
}
};
// 组合节点:包含子节点
class Composite : public Component {
private:
std::vector<std::shared_ptr<Component>> children;
public:
void add(std::shared_ptr<Component> component) override {
children.push_back(component);
}
void remove(std::shared_ptr<Component> component) override {
children.erase(std::remove(children.begin(), children.end(), component), children.end());
}
void operation() override {
std::cout << "Composite: Operation.\n";
for (const auto& child : children) {
child->operation(); // 递归调用子节点
}
}
};
调用方式
cpp
auto leaf1 = std::make_shared<Leaf>();
auto leaf2 = std::make_shared<Leaf>();
auto composite = std::make_shared<Composite>();
composite->add(leaf1);
composite->add(leaf2);
composite->operation(); // 统一调用组合和叶子
类图关系(UML标准表示)
contains <<interface>> Component +add(component) +remove(component) +operation() Leaf +operation() Composite +add(component) +remove(component) +operation()