C++中常用的设计模式源于GoF(Gang of Four)定义的23种经典模式,这些模式可分为创建型、结构型和行为型三大类。以下按类别整理各模式的应用场景、代码示例及注意事项:
一、创建型模式(5种)
创建型模式专注于对象创建过程的封装,降低耦合度。
1. 单例模式(Singleton)
应用场景 :全局只需要一个实例(如配置管理器、日志管理器、线程池)。
代码示例:
cpp
#include <iostream>
#include <mutex>
class Singleton {
private:
// 私有构造函数,禁止外部实例化
Singleton() = default;
// 禁止拷贝和赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton* instance;
static std::mutex mtx; // 线程安全锁
public:
// 全局访问点
static Singleton* getInstance() {
// 双重检查锁定(DCLP),提高效率
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(mtx); // 加锁
if (instance == nullptr) {
instance = new Singleton();
}
}
return instance;
}
void showMessage() {
std::cout << "Singleton Instance" << std::endl;
}
};
// 静态成员初始化
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;
int main() {
Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();
s1->showMessage(); // 输出:Singleton Instance
std::cout << (s1 == s2) << std::endl; // 输出:1(同一实例)
return 0;
}
注意事项:
- 需处理线程安全问题(如双重检查锁定)。
- 避免在析构函数中做复杂操作,可能导致程序退出时崩溃。
- 不适合依赖注入,测试难度较高。
2. 工厂方法模式(Factory Method)
应用场景 :需要延迟对象创建到子类,且客户端无需知道具体产品类型(如日志系统支持文件/控制台输出)。
代码示例:
cpp
#include <iostream>
#include <string>
// 抽象产品
class Logger {
public:
virtual void log(const std::string& message) = 0;
virtual ~Logger() = default;
};
// 具体产品:文件日志
class FileLogger : public Logger {
public:
void log(const std::string& message) override {
std::cout << "File Log: " << message << std::endl;
}
};
// 具体产品:控制台日志
class ConsoleLogger : public Logger {
public:
void log(const std::string& message) override {
std::cout << "Console Log: " << message << std::endl;
}
};
// 抽象工厂
class LoggerFactory {
public:
virtual Logger* createLogger() = 0;
virtual ~LoggerFactory() = default;
};
// 具体工厂:文件日志工厂
class FileLoggerFactory : public LoggerFactory {
public:
Logger* createLogger() override {
return new FileLogger();
}
};
// 具体工厂:控制台日志工厂
class ConsoleLoggerFactory : public LoggerFactory {
public:
Logger* createLogger() override {
return new ConsoleLogger();
}
};
int main() {
LoggerFactory* factory = new ConsoleLoggerFactory();
Logger* logger = factory->createLogger();
logger->log("Hello Factory Method"); // 输出:Console Log: Hello Factory Method
delete logger;
delete factory;
return 0;
}
注意事项:
- 新增产品需新增对应的工厂类,可能导致类数量膨胀。
- 客户端只需依赖抽象工厂和产品,符合依赖倒置原则。
3. 抽象工厂模式(Abstract Factory)
应用场景 :需要创建一系列相互关联的产品族(如跨平台UI组件:Windows按钮+Windows文本框,Linux按钮+Linux文本框)。
代码示例:
cpp
#include <iostream>
// 抽象产品A:按钮
class Button {
public:
virtual void render() = 0;
virtual ~Button() = default;
};
// 具体产品A1:Windows按钮
class WindowsButton : public Button {
public:
void render() override {
std::cout << "Render Windows Button" << std::endl;
}
};
// 具体产品A2:Linux按钮
class LinuxButton : public Button {
public:
void render() override {
std::cout << "Render Linux Button" << std::endl;
}
};
// 抽象产品B:文本框
class TextBox {
public:
virtual void render() = 0;
virtual ~TextBox() = default;
};
// 具体产品B1:Windows文本框
class WindowsTextBox : public TextBox {
public:
void render() override {
std::cout << "Render Windows TextBox" << std::endl;
}
};
// 具体产品B2:Linux文本框
class LinuxTextBox : public TextBox {
public:
void render() override {
std::cout << "Render Linux TextBox" << std::endl;
}
};
// 抽象工厂
class UIFactory {
public:
virtual Button* createButton() = 0;
virtual TextBox* createTextBox() = 0;
virtual ~UIFactory() = default;
};
// 具体工厂1:Windows UI工厂
class WindowsUIFactory : public UIFactory {
public:
Button* createButton() override {
return new WindowsButton();
}
TextBox* createTextBox() override {
return new WindowsTextBox();
}
};
// 具体工厂2:Linux UI工厂
class LinuxUIFactory : public UIFactory {
public:
Button* createButton() override {
return new LinuxButton();
}
TextBox* createTextBox() override {
return new LinuxTextBox();
}
};
int main() {
UIFactory* factory = new LinuxUIFactory();
Button* btn = factory->createButton();
TextBox* txt = factory->createTextBox();
btn->render(); // 输出:Render Linux Button
txt->render(); // 输出:Render Linux TextBox
delete btn;
delete txt;
delete factory;
return 0;
}
注意事项:
- 新增产品族(如MacOS)容易,但新增产品类型(如下拉框)需修改所有工厂类,扩展性受限。
- 确保产品族内的产品相互兼容。
4. 建造者模式(Builder)
应用场景 :复杂对象的构建(如配置项繁多的对象:汽车、文档),需分步构建且隔离构建过程与表示。
代码示例:
cpp
#include <iostream>
#include <string>
#include <vector>
// 产品:电脑
class Computer {
private:
std::string cpu;
std::string ram;
std::string gpu;
public:
void setCPU(const std::string& c) { cpu = c; }
void setRAM(const std::string& r) { ram = r; }
void setGPU(const std::string& g) { gpu = g; }
void show() const {
std::cout << "Computer: CPU=" << cpu
<< ", RAM=" << ram
<< ", GPU=" << gpu << std::endl;
}
};
// 抽象建造者
class ComputerBuilder {
protected:
Computer* computer;
public:
ComputerBuilder() { computer = new Computer(); }
virtual ~ComputerBuilder() { delete computer; }
Computer* getResult() { return computer; }
virtual void buildCPU() = 0;
virtual void buildRAM() = 0;
virtual void buildGPU() = 0;
};
// 具体建造者:游戏电脑
class GamingComputerBuilder : public ComputerBuilder {
public:
void buildCPU() override { computer->setCPU("Intel i9"); }
void buildRAM() override { computer->setRAM("32GB DDR5"); }
void buildGPU() override { computer->setGPU("RTX 4090"); }
};
// 具体建造者:办公电脑
class OfficeComputerBuilder : public ComputerBuilder {
public:
void buildCPU() override { computer->setCPU("Intel i5"); }
void buildRAM() override { computer->setRAM("16GB DDR4"); }
void buildGPU() override { computer->setGPU("Integrated"); }
};
// 指挥者:控制构建流程
class Director {
public:
Computer* construct(ComputerBuilder* builder) {
builder->buildCPU();
builder->buildRAM();
builder->buildGPU();
return builder->getResult();
}
};
int main() {
Director director;
GamingComputerBuilder gamingBuilder;
Computer* gamingPC = director.construct(&gamingBuilder);
gamingPC->show(); // 输出:Computer: CPU=Intel i9, RAM=32GB DDR5, GPU=RTX 4090
OfficeComputerBuilder officeBuilder;
Computer* officePC = director.construct(&officeBuilder);
officePC->show(); // 输出:Computer: CPU=Intel i5, RAM=16GB DDR4, GPU=Integrated
delete gamingPC;
delete officePC;
return 0;
}
注意事项:
- 建造者模式更关注分步构建,而工厂模式关注产品类型创建。
- 若产品结构简单,使用建造者会增加复杂度。
5. 原型模式(Prototype)
应用场景 :对象创建成本高(如数据库连接、大对象复制),需通过复制现有对象快速创建新对象。
代码示例:
cpp
#include <iostream>
#include <string>
#include <memory>
// 抽象原型
class Prototype {
public:
virtual ~Prototype() = default;
virtual std::unique_ptr<Prototype> clone() const = 0;
virtual void show() const = 0;
};
// 具体原型:简历
class Resume : public Prototype {
private:
std::string name;
std::string position;
public:
Resume(std::string n, std::string p) : name(n), position(p) {}
// 深拷贝
std::unique_ptr<Prototype> clone() const override {
return std::make_unique<Resume>(*this);
}
void setPosition(const std::string& p) { position = p; }
void show() const override {
std::cout << "Name: " << name << ", Position: " << position << std::endl;
}
};
int main() {
// 原始对象
auto original = std::make_unique<Resume>("Alice", "Engineer");
original->show(); // 输出:Name: Alice, Position: Engineer
// 克隆对象并修改
auto clone = original->clone();
clone->setPosition("Senior Engineer");
clone->show(); // 输出:Name: Alice, Position: Senior Engineer
return 0;
}
注意事项:
- 需正确实现深拷贝(避免指针浅拷贝导致的资源冲突)。
- 适合对象结构复杂但克隆逻辑简单的场景。
二、结构型模式(7种)
结构型模式关注对象的组合方式,实现更灵活的结构。
6. 适配器模式(Adapter)
应用场景 :将一个类的接口转换为客户端期望的另一个接口(如旧系统接口适配新框架)。
代码示例:
cpp
#include <iostream>
// 目标接口(客户端期望的接口)
class Target {
public:
virtual void request() = 0;
virtual ~Target() = default;
};
// 适配者(需要被适配的旧接口)
class Adaptee {
public:
void specificRequest() {
std::cout << "Adaptee's specific request" << std::endl;
}
};
// 类适配器(继承适配者和目标接口)
class ClassAdapter : public Target, private Adaptee {
public:
void request() override {
specificRequest(); // 调用适配者的方法
}
};
// 对象适配器(持有适配者实例)
class ObjectAdapter : public Target {
private:
Adaptee* adaptee;
public:
ObjectAdapter(Adaptee* a) : adaptee(a) {}
void request() override {
adaptee->specificRequest();
}
};
int main() {
Target* adapter1 = new ClassAdapter();
adapter1->request(); // 输出:Adaptee's specific request
Adaptee adaptee;
Target* adapter2 = new ObjectAdapter(&adaptee);
adapter2->request(); // 输出:Adaptee's specific request
delete adapter1;
delete adapter2;
return 0;
}
注意事项:
- 类适配器通过继承实现,灵活性低;对象适配器通过组合实现,更推荐。
- 避免过度使用,优先考虑接口设计的一致性。
7. 桥接模式(Bridge)
应用场景 :分离抽象与实现,使两者可独立变化(如跨平台图形库:形状抽象与不同平台的绘制实现分离)。
代码示例:
cpp
#include <iostream>
#include <string>
// 实现部分接口
class DrawAPI {
public:
virtual void drawCircle(float x, float y, float radius) = 0;
virtual ~DrawAPI() = default;
};
// 具体实现A:OpenGL绘制
class OpenGLDraw : public DrawAPI {
public:
void drawCircle(float x, float y, float radius) override {
std::cout << "OpenGL Draw Circle: (" << x << "," << y << "), radius=" << radius << std::endl;
}
};
// 具体实现B:DirectX绘制
class DirectXDraw : public DrawAPI {
public:
void drawCircle(float x, float y, float radius) override {
std::cout << "DirectX Draw Circle: (" << x << "," << y << "), radius=" << radius << std::endl;
}
};
// 抽象部分
class Shape {
protected:
DrawAPI* drawAPI; // 桥接:持有实现部分的引用
public:
Shape(DrawAPI* api) : drawAPI(api) {}
virtual ~Shape() = default;
virtual void draw() = 0;
};
// 具体抽象:圆形
class Circle : public Shape {
private:
float x, y, radius;
public:
Circle(float x, float y, float r, DrawAPI* api)
: Shape(api), x(x), y(y), radius(r) {}
void draw() override {
drawAPI->drawCircle(x, y, radius);
}
};
int main() {
// 桥接:圆形 + OpenGL绘制
Shape* circle1 = new Circle(10, 20, 5, new OpenGLDraw());
circle1->draw(); // 输出:OpenGL Draw Circle: (10,20), radius=5
// 桥接:圆形 + DirectX绘制
Shape* circle2 = new Circle(30, 40, 10, new DirectXDraw());
circle2->draw(); // 输出:DirectX Draw Circle: (30,40), radius=10
delete circle1;
delete circle2;
return 0;
}
注意事项:
- 抽象与实现分离后,两者可独立扩展(新增形状或绘制方式无需修改对方)。
- 适合多维度变化的场景(如"形状+颜色""平台+功能")。
8. 组合模式(Composite)
应用场景 :处理树形结构数据(如文件系统、UI组件树),使客户端统一对待单个对象和组合对象。
代码示例:
cpp
#include <iostream>
#include <vector>
#include <string>
// 抽象组件
class Component {
protected:
std::string name;
public:
Component(const std::string& n) : name(n) {}
virtual ~Component() = default;
virtual void add(Component* c) {} // 默认空实现(叶子节点不支持)
virtual void remove(Component* c) {}
virtual void display(int depth) const = 0; // 显示层级结构
};
// 叶子节点:文件
class File : public Component {
public:
File(const std::string& n) : Component(n) {}
void display(int depth) const override {
std::cout << std::string(depth, '-') << name << std::endl;
}
};
// 组合节点:文件夹
class Folder : public Component {
private:
std::vector<Component*> children;
public:
Folder(const std::string& n) : Component(n) {}
void add(Component* c) override {
children.push_back(c);
}
void remove(Component* c) override {
// 简化实现:不实际删除,仅演示
}
void display(int depth) const override {
std::cout << std::string(depth, '-') << name << " (Folder)" << std::endl;
// 递归显示子节点
for (auto child : children) {
child->display(depth + 2);
}
}
~Folder() override {
for (auto child : children) {
delete child;
}
}
};
int main() {
Folder* root = new Folder("Root");
root->add(new File("readme.txt"));
Folder* docs = new Folder("Documents");
docs->add(new File("resume.pdf"));
docs->add(new File("notes.docx"));
root->add(docs);
root->display(1);
// 输出:
// -Root (Folder)
// ---readme.txt
// ---Documents (Folder)
// -----resume.pdf
// -----notes.docx
delete root;
return 0;
}
注意事项:
- 需明确叶子节点和组合节点的职责,避免叶子节点实现不必要的方法(如
add
/remove
)。 - 递归操作时需注意栈溢出风险(深层树形结构)。
9. 装饰模式(Decorator)
应用场景 :动态给对象添加功能(如IO流包装、咖啡加配料),且避免继承导致的类爆炸。
代码示例:
cpp
#include <iostream>
#include <string>
// 抽象组件:咖啡
class Coffee {
public:
virtual std::string getDescription() const = 0;
virtual double cost() const = 0;
virtual ~Coffee() = default;
};
// 具体组件:黑咖啡
class Espresso : public Coffee {
public:
std::string getDescription() const override {
return "Espresso";
}
double cost() const override {
return 2.0;
}
};
// 装饰器基类(继承并持有组件)
class Decorator : public Coffee {
protected:
Coffee* coffee; // 被装饰的对象
public:
Decorator(Coffee* c) : coffee(c) {}
~Decorator() override { delete coffee; }
};
// 具体装饰器:牛奶
class Milk : public Decorator {
public:
Milk(Coffee* c) : Decorator(c) {}
std::string getDescription() const override {
return coffee->getDescription() + ", Milk";
}
double cost() const override {
return coffee->cost() + 0.5;
}
};
// 具体装饰器:糖
class Sugar : public Decorator {
public:
Sugar(Coffee* c) : Decorator(c) {}
std::string getDescription() const override {
return coffee->getDescription() + ", Sugar";
}
double cost() const override {
return coffee->cost() + 0.3;
}
};
int main() {
Coffee* coffee = new Espresso();
coffee = new Milk(coffee);
coffee = new Sugar(coffee);
std::cout << "Description: " << coffee->getDescription() << std::endl; // 输出:Espresso, Milk, Sugar
std::cout << "Cost: $" << coffee->cost() << std::endl; // 输出:$2.8
delete coffee;
return 0;
}
注意事项:
- 装饰器和被装饰对象必须实现同一接口。
- 避免多层装饰导致的复杂性(如调试困难)。
10. 外观模式(Facade)
应用场景 :为复杂子系统提供统一接口(如智能家居控制中心,统一控制灯光、空调、窗帘)。
代码示例:
cpp
#include <iostream>
// 子系统1:灯光
class Light {
public:
void turnOn() { std::cout << "Light is on" << std::endl; }
void turnOff() { std::cout << "Light is off" << std::endl; }
};
// 子系统2:空调
class AirConditioner {
public:
void start() { std::cout << "AC is running" << std::endl; }
void stop() { std::cout << "AC is stopped" << std::endl; }
};
// 外观类:智能家居控制中心
class SmartHomeFacade {
private:
Light light;
AirConditioner ac;
public:
// 统一接口:离家模式
void leaveHome() {
light.turnOff();
ac.stop();
std::cout << "Leaving home, all devices off" << std::endl;
}
// 统一接口:回家模式
void arriveHome() {
light.turnOn();
ac.start();
std::cout << "Welcome home, devices activated" << std::endl;
}
};
int main() {
SmartHomeFacade home;
home.arriveHome();
// 输出:
// Light is on
// AC is running
// Welcome home, devices activated
home.leaveHome();
// 输出:
// Light is off
// AC is stopped
// Leaving home, all devices off
return 0;
}
注意事项:
- 外观模式不封装子系统,客户端仍可直接访问子系统(灵活性)。
- 避免外观类过于庞大,可拆分多个外观类。
11. 享元模式(Flyweight)
应用场景 :大量相似对象占用内存(如游戏中的树木、文字处理中的字符),通过共享对象减少内存消耗。
代码示例:
cpp
#include <iostream>
#include <unordered_map>
#include <string>
// 享元类:树的共享属性
class TreeType {
private:
std::string name; // 树种(如松树、橡树)
std::string color;
public:
TreeType(std::string n, std::string c) : name(n), color(c) {}
void draw(int x, int y) const { // x,y是非共享的外部状态
std::cout << "Draw " << name << " (color: " << color
<< ") at (" << x << "," << y << ")" << std::endl;
}
};
// 享元工厂:管理共享对象
class TreeTypeFactory {
private:
std::unordered_map<std::string, TreeType*> types; // 缓存池
public:
TreeType* getTreeType(const std::string& name, const std::string& color) {
std::string key = name + "_" + color;
if (types.find(key) == types.end()) {
types[key] = new TreeType(name, color); // 不存在则创建
}
return types[key]; // 返回共享对象
}
~TreeTypeFactory() {
for (auto& pair : types) {
delete pair.second;
}
}
};
// 树对象(包含共享和非共享状态)
class Tree {
private:
int x, y; // 非共享状态:位置
TreeType* type; // 共享状态
public:
Tree(int x, int y, TreeType* t) : x(x), y(y), type(t) {}
void draw() const {
type->draw(x, y);
}
};
int main() {
TreeTypeFactory factory;
// 共享同一棵树的类型
Tree* tree1 = new Tree(10, 20, factory.getTreeType("Pine", "Green"));
Tree* tree2 = new Tree(30, 40, factory.getTreeType("Pine", "Green"));
Tree* tree3 = new Tree(50, 60, factory.getTreeType("Oak", "Brown"));
tree1->draw(); // 输出:Draw Pine (color: Green) at (10,20)
tree2->draw(); // 输出:Draw Pine (color: Green) at (30,40)
tree3->draw(); // 输出:Draw Oak (color: Brown) at (50,60)
delete tree1;
delete tree2;
delete tree3;
return 0;
}
注意事项:
- 区分内部状态(可共享)和外部状态(不可共享,需客户端传入)。
- 适合对象数量庞大且相似性高的场景,否则可能增加复杂度。
12. 代理模式(Proxy)
应用场景 :控制对对象的访问(如远程代理、延迟加载、权限控制)。
代码示例:
cpp
#include <iostream>
#include <string>
// 抽象主题:图片
class Image {
public:
virtual void display() = 0;
virtual ~Image() = default;
};
// 真实主题:高清图片(加载成本高)
class HighResImage : public Image {
private:
std::string filename;
void loadFromDisk() { // 模拟耗时加载
std::cout << "Loading " << filename << " from disk..." << std::endl;
}
public:
HighResImage(const std::string& fn) : filename(fn) {
loadFromDisk(); // 构造时加载
}
void display() override {
std::cout << "Displaying " << filename << std::endl;
}
};
// 代理:延迟加载代理(需要时才加载真实图片)
class ImageProxy : public Image {
private:
std::string filename;
HighResImage* realImage; // 真实对象(延迟初始化)
public:
ImageProxy(const std::string& fn) : filename(fn), realImage(nullptr) {}
void display() override {
if (realImage == nullptr) {
realImage = new HighResImage(filename); // 需要时才加载
}
realImage->display();
}
~ImageProxy() override {
delete realImage;
}
};
int main() {
Image* image = new ImageProxy("photo.jpg");
std::cout << "Image created, not loaded yet" << std::endl;
// 首次显示时才加载
image->display();
// 输出:
// Loading photo.jpg from disk...
// Displaying photo.jpg
// 再次显示,无需重新加载
image->display(); // 输出:Displaying photo.jpg
delete image;
return 0;
}
注意事项:
- 代理与真实对象需实现同一接口,保证透明性。
- 避免过度使用,简单场景直接访问对象更高效。
三、行为型模式(11种)
行为型模式关注对象间的交互与职责分配。
13. 职责链模式(Chain of Responsibility)
应用场景 :请求需要多个对象处理,且处理者不确定(如日志级别过滤、事件冒泡)。
代码示例:
cpp
#include <iostream>
#include <string>
// 抽象处理者
class Logger {
protected:
Logger* next; // 下一个处理者
int level; // 处理级别
public:
Logger(int l, Logger* n) : level(l), next(n) {}
virtual ~Logger() { delete next; }
void log(int msgLevel, const std::string& message) {
if (msgLevel >= level) {
write(message); // 当前处理者处理
}
if (next != nullptr) {
next->log(msgLevel, message); // 传递给下一个
}
}
virtual void write(const std::string& message) = 0;
};
// 具体处理者:控制台日志(级别1)
class ConsoleLogger : public Logger {
public:
ConsoleLogger(int l, Logger* n) : Logger(l, n) {}
void write(const std::string& message) override {
std::cout << "Console: " << message << std::endl;
}
};
// 具体处理者:文件日志(级别2)
class FileLogger : public Logger {
public:
FileLogger(int l, Logger* n) : Logger(l, n) {}
void write(const std::string& message) override {
std::cout << "File: " << message << std::endl;
}
};
// 具体处理者:数据库日志(级别3)
class DatabaseLogger : public Logger {
public:
DatabaseLogger(int l, Logger* n) : Logger(l, n) {}
void write(const std::string& message) override {
std::cout << "Database: " << message << std::endl;
}
};
int main() {
// 构建职责链:Database -> File -> Console
Logger* logger = new DatabaseLogger(3,
new FileLogger(2,
new ConsoleLogger(1, nullptr)));
logger->log(1, "Debug message"); // 仅Console处理
// 输出:Console: Debug message
logger->log(2, "Warning message"); // File和Console处理
// 输出:
// File: Warning message
// Console: Warning message
delete logger;
return 0;
}
注意事项:
- 请求可能未被任何处理者处理,需考虑默认处理机制。
- 链的构建由客户端负责,需避免过长的链导致性能问题。
14. 命令模式(Command)
应用场景 :将请求封装为对象(如菜单操作、撤销/重做功能、任务队列)。
代码示例:
cpp
#include <iostream>
#include <vector>
#include <string>
// 接收者:灯
class Light {
private:
std::string location;
public:
Light(std::string loc) : location(loc) {}
void on() { std::cout << location << " Light is on" << std::endl; }
void off() { std::cout << location << " Light is off" << std::endl; }
};
// 抽象命令
class Command {
public:
virtual void execute() = 0;
virtual void undo() = 0;
virtual ~Command() = default;
};
// 具体命令:开灯
class LightOnCommand : public Command {
private:
Light* light;
public:
LightOnCommand(Light* l) : light(l) {}
void execute() override { light->on(); }
void undo() override { light->off(); } // 撤销:关灯
};
// 具体命令:关灯
class LightOffCommand : public Command {
private:
Light* light;
public:
LightOffCommand(Light* l) : light(l) {}
void execute() override { light->off(); }
void undo() override { light->on(); } // 撤销:开灯
};
// 调用者:遥控器
class RemoteControl {
private:
Command* onCommand;
Command* offCommand;
Command* lastCommand; // 记录最后执行的命令(用于撤销)
public:
void setCommands(Command* on, Command* off) {
onCommand = on;
offCommand = off;
}
void pressOn() {
onCommand->execute();
lastCommand = onCommand;
}
void pressOff() {
offCommand->execute();
lastCommand = offCommand;
}
void pressUndo() {
if (lastCommand != nullptr) {
lastCommand->undo();
}
}
};
int main() {
Light* livingRoomLight = new Light("Living Room");
Command* lightOn = new LightOnCommand(livingRoomLight);
Command* lightOff = new LightOffCommand(livingRoomLight);
RemoteControl remote;
remote.setCommands(lightOn, lightOff);
remote.pressOn(); // 输出:Living Room Light is on
remote.pressOff(); // 输出:Living Room Light is off
remote.pressUndo(); // 输出:Living Room Light is on(撤销关灯)
delete lightOn;
delete lightOff;
delete livingRoomLight;
return 0;
}
注意事项:
- 命令对象可能持有接收者引用,需注意生命周期管理。
- 适合需要日志记录、事务回滚的场景。
15. 解释器模式(Interpreter)
应用场景 :解析特定语法规则的语言(如简单表达式解析、正则表达式引擎)。
代码示例:
cpp
#include <iostream>
#include <string>
#include <memory>
// 抽象表达式
class Expression {
public:
virtual int interpret() = 0;
virtual ~Expression() = default;
};
// 终结符表达式:数字
class Number : public Expression {
private:
int value;
public:
Number(int v) : value(v) {}
int interpret() override { return value; }
};
// 非终结符表达式:加法
class Add : public Expression {
private:
std::unique_ptr<Expression> left;
std::unique_ptr<Expression> right;
public:
Add(Expression* l, Expression* r)
: left(l), right(r) {}
int interpret() override {
return left->interpret() + right->interpret();
}
};
// 非终结符表达式:乘法
class Multiply : public Expression {
private:
std::unique_ptr<Expression> left;
std::unique_ptr<Expression> right;
public:
Multiply(Expression* l, Expression* r)
: left(l), right(r) {}
int interpret() override {
return left->interpret() * right->interpret();
}
};
int main() {
// 解析表达式:(3 + 4) * 5
Expression* expr = new Multiply(
new Add(new Number(3), new Number(4)),
new Number(5)
);
std::cout << "Result: " << expr->interpret() << std::endl; // 输出:35
delete expr;
return 0;
}
注意事项:
- 适合简单语法,复杂语法会导致表达式类爆炸(如支持减法、除法等)。
- 可结合语法分析器生成工具(如ANTLR)使用。
16. 迭代器模式(Iterator)
应用场景 :遍历聚合对象(如容器),且不暴露其内部结构(C++ STL的std::iterator
是典型实现)。
代码示例:
cpp
#include <iostream>
#include <string>
// 前向声明
template <typename T>
class Iterator;
// 抽象聚合
template <typename T>
class Aggregate {
public:
virtual Iterator<T>* createIterator() = 0;
virtual int getSize() = 0;
virtual T getItem(int index) = 0;
virtual ~Aggregate() = default;
};
// 抽象迭代器
template <typename T>
class Iterator {
public:
virtual bool hasNext() = 0;
virtual T next() = 0;
virtual ~Iterator() = default;
};
// 具体聚合:数组
template <typename T>
class ArrayAggregate : public Aggregate<T> {
private:
T* items;
int size;
public:
ArrayAggregate(T* arr, int s) : items(arr), size(s) {}
Iterator<T>* createIterator() override;
int getSize() override { return size; }
T getItem(int index) override { return items[index]; }
};
// 具体迭代器:数组迭代器
template <typename T>
class ArrayIterator : public Iterator<T> {
private:
ArrayAggregate<T>* aggregate;
int index;
public:
ArrayIterator(ArrayAggregate<T>* a) : aggregate(a), index(0) {}
bool hasNext() override {
return index < aggregate->getSize();
}
T next() override {
return aggregate->getItem(index++);
}
};
// 实现聚合的createIterator
template <typename T>
Iterator<T>* ArrayAggregate<T>::createIterator() {
return new ArrayIterator<T>(this);
}
int main() {
std::string names[] = {"Alice", "Bob", "Charlie"};
ArrayAggregate<std::string> aggregate(names, 3);
Iterator<std::string>* it = aggregate.createIterator();
while (it->hasNext()) {
std::cout << it->next() << std::endl;
// 输出:Alice, Bob, Charlie
}
delete it;
return 0;
}
注意事项:
- C++ STL已提供完善的迭代器,无需重复实现。
- 迭代器应支持失效检测(如容器修改后迭代器失效)。
17. 中介者模式(Mediator)
应用场景 :多个对象相互依赖(如聊天室、GUI组件交互),通过中介者减少直接耦合。
代码示例:
cpp
#include <iostream>
#include <string>
#include <vector>
// 前向声明
class Colleague;
// 抽象中介者
class Mediator {
public:
virtual void send(const std::string& message, Colleague* sender) = 0;
virtual ~Mediator() = default;
};
// 抽象同事
class Colleague {
protected:
Mediator* mediator;
public:
Colleague(Mediator* m) : mediator(m) {}
virtual void send(const std::string& message) = 0;
virtual void receive(const std::string& message) = 0;
virtual ~Colleague() = default;
};
// 具体中介者:聊天室
class ChatRoom : public Mediator {
private:
std::vector<Colleague*> colleagues;
public:
void addColleague(Colleague* c) {
colleagues.push_back(c);
}
void send(const std::string& message, Colleague* sender) override {
// 转发消息给所有非发送者的同事
for (auto colleague : colleagues) {
if (colleague != sender) {
colleague->receive(message);
}
}
}
};
// 具体同事:用户
class User : public Colleague {
private:
std::string name;
public:
User(std::string n, Mediator* m) : Colleague(m), name(n) {}
void send(const std::string& message) override {
std::cout << name << " sends: " << message << std::endl;
mediator->send(message, this);
}
void receive(const std::string& message) override {
std::cout << name << " receives: " << message << std::endl;
}
};
int main() {
ChatRoom* chat = new ChatRoom();
User* alice = new User("Alice", chat);
User* bob = new User("Bob", chat);
chat->addColleague(alice);
chat->addColleague(bob);
alice->send("Hi Bob!");
// 输出:
// Alice sends: Hi Bob!
// Bob receives: Hi Bob!
bob->send("Hello Alice!");
// 输出:
// Bob sends: Hello Alice!
// Alice receives: Hello Alice!
delete alice;
delete bob;
delete chat;
return 0;
}
注意事项:
- 中介者可能成为"上帝类"(过度集中逻辑),需合理拆分。
- 适合交互复杂但规则固定的场景。
18. 备忘录模式(Memento)
应用场景 :保存对象状态以便后续恢复(如游戏存档、编辑器撤销功能)。
代码示例:
cpp
#include <iostream>
#include <string>
#include <vector>
// 备忘录:保存状态
class Memento {
private:
std::string state;
// 仅允许Originator访问构造函数
Memento(const std::string& s) : state(s) {}
friend class Originator;
public:
std::string getState() const { return state; }
};
// 原发器:创建并恢复备忘录
class Originator {
private:
std::string state;
public:
void setState(const std::string& s) {
std::cout << "Setting state to: " << s << std::endl;
state = s;
}
Memento* saveToMemento() {
return new Memento(state);
}
void restoreFromMemento(Memento* m) {
state = m->getState();
std::cout << "Restored state to: " << state << std::endl;
}
};
// 管理者:保存备忘录
class Caretaker {
private:
std::vector<Memento*> mementos;
public:
void addMemento(Memento* m) {
mementos.push_back(m);
}
Memento* getMemento(int index) {
return mementos[index];
}
~Caretaker() {
for (auto m : mementos) {
delete m;
}
}
};
int main() {
Originator originator;
Caretaker caretaker;
originator.setState("State 1");
caretaker.addMemento(originator.saveToMemento());
originator.setState("State 2");
caretaker.addMemento(originator.saveToMemento());
originator.setState("State 3");
// 恢复到State 1
originator.restoreFromMemento(caretaker.getMemento(0)); // 输出:Restored state to: State 1
return 0;
}
注意事项:
- 备忘录可能占用大量内存(如频繁保存大对象状态)。
- 需控制备忘录的访问权限(避免外部修改)。
19. 观察者模式(Observer)
应用场景 :对象状态变化时通知依赖它的其他对象(如发布-订阅模型、事件监听)。
代码示例:
cpp
#include <iostream>
#include <vector>
#include <string>
// 前向声明
class Subject;
// 抽象观察者
class Observer {
public:
virtual void update(Subject* subject) = 0;
virtual ~Observer() = default;
};
// 抽象主题
class Subject {
private:
std::vector<Observer*> observers;
public:
void attach(Observer* o) {
observers.push_back(o);
}
void detach(Observer* o) {
// 简化实现:不实际删除
}
void notify() {
for (auto observer : observers) {
observer->update(this);
}
}
virtual std::string getState() = 0;
virtual void setState(const std::string& s) = 0;
};
// 具体主题:报纸
class Newspaper : public Subject {
private:
std::string news;
public:
std::string getState() override { return news; }
void setState(const std::string& s) override {
news = s;
notify(); // 状态变化时通知观察者
}
};
// 具体观察者:读者
class Reader : public Observer {
private:
std::string name;
public:
Reader(std::string n) : name(n) {}
void update(Subject* subject) override {
std::cout << name << " received news: " << subject->getState() << std::endl;
}
};
int main() {
Newspaper newspaper;
Reader alice("Alice");
Reader bob("Bob");
newspaper.attach(&alice);
newspaper.attach(&bob);
newspaper.setState("Breaking News: Design Patterns!");
// 输出:
// Alice received news: Breaking News: Design Patterns!
// Bob received news: Breaking News: Design Patterns!
return 0;
}
注意事项:
- 需处理观察者的生命周期(避免通知已销毁的观察者)。
- 可支持观察者选择感兴趣的事件类型(过滤通知)。
20. 状态模式(State)
应用场景 :对象状态变化时行为随之改变(如订单状态流转、电梯运行状态)。
代码示例:
cpp
#include <iostream>
#include <string>
// 前向声明
class Context;
// 抽象状态
class State {
public:
virtual void handle(Context* context) = 0;
virtual std::string getName() = 0;
virtual ~State() = default;
};
// 具体状态:已下单
class OrderedState : public State {
public:
void handle(Context* context) override;
std::string getName() override { return "Ordered"; }
};
// 具体状态:已付款
class PaidState : public State {
public:
void handle(Context* context) override;
std::string getName() override { return "Paid"; }
};
// 具体状态:已发货
class ShippedState : public State {
public:
void handle(Context* context) override;
std::string getName() override { return "Shipped"; }
};
// 上下文:订单
class Context {
private:
State* currentState;
public:
Context() {
currentState = new OrderedState(); // 初始状态
std::cout << "Order state: " << currentState->getName() << std::endl;
}
void setState(State* s) {
delete currentState;
currentState = s;
std::cout << "Order state changed to: " << currentState->getName() << std::endl;
}
void nextState() {
currentState->handle(this);
}
~Context() {
delete currentState;
}
};
// 实现状态转换逻辑
void OrderedState::handle(Context* context) {
context->setState(new PaidState());
}
void PaidState::handle(Context* context) {
context->setState(new ShippedState());
}
void ShippedState::handle(Context* context) {
std::cout << "Order already shipped, no next state" << std::endl;
}
int main() {
Context order;
order.nextState(); // 已下单 -> 已付款
order.nextState(); // 已付款 -> 已发货
order.nextState(); // 已发货(无后续状态)
// 输出:
// Order state: Ordered
// Order state changed to: Paid
// Order state changed to: Shipped
// Order already shipped, no next state
return 0;
}
注意事项:
- 状态转换逻辑集中在状态类中,避免上下文类中出现大量
if-else
。 - 适合状态数量固定且转换规则明确的场景。
21. 策略模式(Strategy)
应用场景 :多种算法可选(如排序算法、支付方式),需动态切换且避免if-else
判断。
代码示例:
cpp
#include <iostream>
#include <string>
// 抽象策略:支付方式
class PaymentStrategy {
public:
virtual void pay(double amount) = 0;
virtual ~PaymentStrategy() = default;
};
// 具体策略:信用卡支付
class CreditCardPayment : public PaymentStrategy {
private:
std::string cardNumber;
public:
CreditCardPayment(std::string num) : cardNumber(num) {}
void pay(double amount) override {
std::cout << "Paid $" << amount << " with Credit Card: " << cardNumber << std::endl;
}
};
// 具体策略:支付宝支付
class AlipayPayment : public PaymentStrategy {
private:
std::string username;
public:
AlipayPayment(std::string name) : username(name) {}
void pay(double amount) override {
std::cout << "Paid $" << amount << " with Alipay: " << username << std::endl;
}
};
// 上下文:购物车
class ShoppingCart {
private:
PaymentStrategy* paymentStrategy;
public:
void setPaymentStrategy(PaymentStrategy* s) {
paymentStrategy = s;
}
void checkout(double amount) {
paymentStrategy->pay(amount);
}
};
int main() {
ShoppingCart cart;
// 使用信用卡支付
cart.setPaymentStrategy(new CreditCardPayment("1234-5678-9012"));
cart.checkout(99.99); // 输出:Paid $99.99 with Credit Card: 1234-5678-9012
// 切换为支付宝支付
cart.setPaymentStrategy(new AlipayPayment("user@example.com"));
cart.checkout(49.99); // 输出:Paid $49.99 with Alipay: user@example.com
return 0;
}
注意事项:
- 客户端需知道所有策略类,以便选择合适的策略。
- 策略间应无状态,可共享实例(如使用单例)。
22. 模板方法模式(Template Method)
应用场景 :算法骨架固定,但部分步骤可变(如流程化任务:数据处理、游戏角色升级)。
代码示例:
cpp
#include <iostream>
#include <string>
// 抽象类:定义模板方法
class DataProcessor {
public:
// 模板方法:固定算法骨架
void process() {
readData();
analyzeData();
writeReport();
}
virtual ~DataProcessor() = default;
protected:
// 抽象步骤(子类实现)
virtual void readData() = 0;
virtual void analyzeData() = 0;
// 具体步骤(父类实现,可选)
void writeReport() {
std::cout << "Generating standard report..." << std::endl;
}
};
// 具体子类:处理CSV数据
class CsvProcessor : public DataProcessor {
protected:
void readData() override {
std::cout << "Reading data from CSV file" << std::endl;
}
void analyzeData() override {
std::cout << "Analyzing CSV data" << std::endl;
}
};
// 具体子类:处理数据库数据
class DbProcessor : public DataProcessor {
protected:
void readData() override {
std::cout << "Reading data from database" << std::endl;
}
void analyzeData() override {
std::cout << "Analyzing database data" << std::endl;
}
// 重写钩子方法(可选)
void writeReport() override {
std::cout << "Generating database-specific report..." << std::endl;
}
};
int main() {
DataProcessor* csv = new CsvProcessor();
csv->process();
// 输出:
// Reading data from CSV file
// Analyzing CSV data
// Generating standard report...
DataProcessor* db = new DbProcessor();
db->process();
// 输出:
// Reading data from database
// Analyzing database data
// Generating database-specific report...
delete csv;
delete db;
return 0;
}
注意事项:
- 模板方法通常声明为
final
,防止子类重写算法骨架。 - 钩子方法(
hook
)可让子类选择性扩展步骤。
23. 访问者模式(Visitor)
应用场景 :为复杂对象结构(如组合模式的树形结构)添加新操作,且不修改对象类(如文档导出、数据统计)。
代码示例:
cpp
#include <iostream>
#include <string>
#include <vector>
// 前向声明
class ElementA;
class ElementB;
// 抽象访问者
class Visitor {
public:
virtual void visit(ElementA* element) = 0;
virtual void visit(ElementB* element) = 0;
virtual ~Visitor() = default;
};
// 抽象元素
class Element {
public:
virtual void accept(Visitor* visitor) = 0; // 接受访问者
virtual ~Element() = default;
};
// 具体元素A
class ElementA : public Element {
private:
std::string data;
public:
ElementA(std::string d) : data(d) {}
std::string getData() const { return data; }
void accept(Visitor* visitor) override {
visitor->visit(this); // 调用访问者的对应方法
}
};
// 具体元素B
class ElementB : public Element {
private:
int value;
public:
ElementB(int v) : value(v) {}
int getValue() const { return value; }
void accept(Visitor* visitor) override {
visitor->visit(this);
}
};
// 对象结构:管理元素集合
class ObjectStructure {
private:
std::vector<Element*> elements;
public:
void addElement(Element* e) {
elements.push_back(e);
}
void accept(Visitor* visitor) {
for (auto e : elements) {
e->accept(visitor);
}
}
~ObjectStructure() {
for (auto e : elements) {
delete e;
}
}
};
// 具体访问者:打印访问者
class PrintVisitor : public Visitor {
public:
void visit(ElementA* element) override {
std::cout << "ElementA data: " << element->getData() << std::endl;
}
void visit(ElementB* element) override {
std::cout << "ElementB value: " << element->getValue() << std::endl;
}
};
// 具体访问者:计算访问者(对ElementB求和)
class SumVisitor : public Visitor {
private:
int sum = 0;
public:
void visit(ElementA* element) override {
// 不处理ElementA
}
void visit(ElementB* element) override {
sum += element->getValue();
}
int getSum() const { return sum; }
};
int main() {
ObjectStructure structure;
structure.addElement(new ElementA("Hello"));
structure.addElement(new ElementB(10));
structure.addElement(new ElementB(20));
// 打印元素
PrintVisitor printVisitor;
structure.accept(&printVisitor);
// 输出:
// ElementA data: Hello
// ElementB value: 10
// ElementB value: 20
// 计算ElementB的和
SumVisitor sumVisitor;
structure.accept(&sumVisitor);
std::cout << "Sum of ElementB values: " << sumVisitor.getSum() << std::endl; // 输出:30
return 0;
}
注意事项:
- 元素类新增时,需修改所有访问者类,违反开闭原则。
- 适合元素结构稳定,但操作频繁变化的场景。
总结
设计模式的核心是"解耦"和"复用",选择模式时需结合具体场景,避免过度设计。实际开发中,应优先使用C++标准库或成熟框架中已实现的模式(如STL的迭代器、智能指针的RAII模式),而非重复造轮子。C++中常用的设计模式源于GoF(Gang of Four)定义的23种经典模式,这些模式可分为创建型、结构型和行为型三大类。以下按类别整理各模式的应用场景、代码示例及注意事项:
一、创建型模式(5种)
创建型模式专注于对象创建过程的封装,降低耦合度。
1. 单例模式(Singleton)
应用场景 :全局只需要一个实例(如配置管理器、日志管理器、线程池)。
代码示例:
cpp
#include <iostream>
#include <mutex>
class Singleton {
private:
// 私有构造函数,禁止外部实例化
Singleton() = default;
// 禁止拷贝和赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
static Singleton* instance;
static std::mutex mtx; // 线程安全锁
public:
// 全局访问点
static Singleton* getInstance() {
// 双重检查锁定(DCLP),提高效率
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(mtx); // 加锁
if (instance == nullptr) {
instance = new Singleton();
}
}
return instance;
}
void showMessage() {
std::cout << "Singleton Instance" << std::endl;
}
};
// 静态成员初始化
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;
int main() {
Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();
s1->showMessage(); // 输出:Singleton Instance
std::cout << (s1 == s2) << std::endl; // 输出:1(同一实例)
return 0;
}
注意事项:
- 需处理线程安全问题(如双重检查锁定)。
- 避免在析构函数中做复杂操作,可能导致程序退出时崩溃。
- 不适合依赖注入,测试难度较高。
2. 工厂方法模式(Factory Method)
应用场景 :需要延迟对象创建到子类,且客户端无需知道具体产品类型(如日志系统支持文件/控制台输出)。
代码示例:
cpp
#include <iostream>
#include <string>
// 抽象产品
class Logger {
public:
virtual void log(const std::string& message) = 0;
virtual ~Logger() = default;
};
// 具体产品:文件日志
class FileLogger : public Logger {
public:
void log(const std::string& message) override {
std::cout << "File Log: " << message << std::endl;
}
};
// 具体产品:控制台日志
class ConsoleLogger : public Logger {
public:
void log(const std::string& message) override {
std::cout << "Console Log: " << message << std::endl;
}
};
// 抽象工厂
class LoggerFactory {
public:
virtual Logger* createLogger() = 0;
virtual ~LoggerFactory() = default;
};
// 具体工厂:文件日志工厂
class FileLoggerFactory : public LoggerFactory {
public:
Logger* createLogger() override {
return new FileLogger();
}
};
// 具体工厂:控制台日志工厂
class ConsoleLoggerFactory : public LoggerFactory {
public:
Logger* createLogger() override {
return new ConsoleLogger();
}
};
int main() {
LoggerFactory* factory = new ConsoleLoggerFactory();
Logger* logger = factory->createLogger();
logger->log("Hello Factory Method"); // 输出:Console Log: Hello Factory Method
delete logger;
delete factory;
return 0;
}
注意事项:
- 新增产品需新增对应的工厂类,可能导致类数量膨胀。
- 客户端只需依赖抽象工厂和产品,符合依赖倒置原则。
3. 抽象工厂模式(Abstract Factory)
应用场景 :需要创建一系列相互关联的产品族(如跨平台UI组件:Windows按钮+Windows文本框,Linux按钮+Linux文本框)。
代码示例:
cpp
#include <iostream>
// 抽象产品A:按钮
class Button {
public:
virtual void render() = 0;
virtual ~Button() = default;
};
// 具体产品A1:Windows按钮
class WindowsButton : public Button {
public:
void render() override {
std::cout << "Render Windows Button" << std::endl;
}
};
// 具体产品A2:Linux按钮
class LinuxButton : public Button {
public:
void render() override {
std::cout << "Render Linux Button" << std::endl;
}
};
// 抽象产品B:文本框
class TextBox {
public:
virtual void render() = 0;
virtual ~TextBox() = default;
};
// 具体产品B1:Windows文本框
class WindowsTextBox : public TextBox {
public:
void render() override {
std::cout << "Render Windows TextBox" << std::endl;
}
};
// 具体产品B2:Linux文本框
class LinuxTextBox : public TextBox {
public:
void render() override {
std::cout << "Render Linux TextBox" << std::endl;
}
};
// 抽象工厂
class UIFactory {
public:
virtual Button* createButton() = 0;
virtual TextBox* createTextBox() = 0;
virtual ~UIFactory() = default;
};
// 具体工厂1:Windows UI工厂
class WindowsUIFactory : public UIFactory {
public:
Button* createButton() override {
return new WindowsButton();
}
TextBox* createTextBox() override {
return new WindowsTextBox();
}
};
// 具体工厂2:Linux UI工厂
class LinuxUIFactory : public UIFactory {
public:
Button* createButton() override {
return new LinuxButton();
}
TextBox* createTextBox() override {
return new LinuxTextBox();
}
};
int main() {
UIFactory* factory = new LinuxUIFactory();
Button* btn = factory->createButton();
TextBox* txt = factory->createTextBox();
btn->render(); // 输出:Render Linux Button
txt->render(); // 输出:Render Linux TextBox
delete btn;
delete txt;
delete factory;
return 0;
}
注意事项:
- 新增产品族(如MacOS)容易,但新增产品类型(如下拉框)需修改所有工厂类,扩展性受限。
- 确保产品族内的产品相互兼容。
4. 建造者模式(Builder)
应用场景 :复杂对象的构建(如配置项繁多的对象:汽车、文档),需分步构建且隔离构建过程与表示。
代码示例:
cpp
#include <iostream>
#include <string>
#include <vector>
// 产品:电脑
class Computer {
private:
std::string cpu;
std::string ram;
std::string gpu;
public:
void setCPU(const std::string& c) { cpu = c; }
void setRAM(const std::string& r) { ram = r; }
void setGPU(const std::string& g) { gpu = g; }
void show() const {
std::cout << "Computer: CPU=" << cpu
<< ", RAM=" << ram
<< ", GPU=" << gpu << std::endl;
}
};
// 抽象建造者
class ComputerBuilder {
protected:
Computer* computer;
public:
ComputerBuilder() { computer = new Computer(); }
virtual ~ComputerBuilder() { delete computer; }
Computer* getResult() { return computer; }
virtual void buildCPU() = 0;
virtual void buildRAM() = 0;
virtual void buildGPU() = 0;
};
// 具体建造者:游戏电脑
class GamingComputerBuilder : public ComputerBuilder {
public:
void buildCPU() override { computer->setCPU("Intel i9"); }
void buildRAM() override { computer->setRAM("32GB DDR5"); }
void buildGPU() override { computer->setGPU("RTX 4090"); }
};
// 具体建造者:办公电脑
class OfficeComputerBuilder : public ComputerBuilder {
public:
void buildCPU() override { computer->setCPU("Intel i5"); }
void buildRAM() override { computer->setRAM("16GB DDR4"); }
void buildGPU() override { computer->setGPU("Integrated"); }
};
// 指挥者:控制构建流程
class Director {
public:
Computer* construct(ComputerBuilder* builder) {
builder->buildCPU();
builder->buildRAM();
builder->buildGPU();
return builder->getResult();
}
};
int main() {
Director director;
GamingComputerBuilder gamingBuilder;
Computer* gamingPC = director.construct(&gamingBuilder);
gamingPC->show(); // 输出:Computer: CPU=Intel i9, RAM=32GB DDR5, GPU=RTX 4090
OfficeComputerBuilder officeBuilder;
Computer* officePC = director.construct(&officeBuilder);
officePC->show(); // 输出:Computer: CPU=Intel i5, RAM=16GB DDR4, GPU=Integrated
delete gamingPC;
delete officePC;
return 0;
}
注意事项:
- 建造者模式更关注分步构建,而工厂模式关注产品类型创建。
- 若产品结构简单,使用建造者会增加复杂度。
5. 原型模式(Prototype)
应用场景 :对象创建成本高(如数据库连接、大对象复制),需通过复制现有对象快速创建新对象。
代码示例:
cpp
#include <iostream>
#include <string>
#include <memory>
// 抽象原型
class Prototype {
public:
virtual ~Prototype() = default;
virtual std::unique_ptr<Prototype> clone() const = 0;
virtual void show() const = 0;
};
// 具体原型:简历
class Resume : public Prototype {
private:
std::string name;
std::string position;
public:
Resume(std::string n, std::string p) : name(n), position(p) {}
// 深拷贝
std::unique_ptr<Prototype> clone() const override {
return std::make_unique<Resume>(*this);
}
void setPosition(const std::string& p) { position = p; }
void show() const override {
std::cout << "Name: " << name << ", Position: " << position << std::endl;
}
};
int main() {
// 原始对象
auto original = std::make_unique<Resume>("Alice", "Engineer");
original->show(); // 输出:Name: Alice, Position: Engineer
// 克隆对象并修改
auto clone = original->clone();
clone->setPosition("Senior Engineer");
clone->show(); // 输出:Name: Alice, Position: Senior Engineer
return 0;
}
注意事项:
- 需正确实现深拷贝(避免指针浅拷贝导致的资源冲突)。
- 适合对象结构复杂但克隆逻辑简单的场景。
二、结构型模式(7种)
结构型模式关注对象的组合方式,实现更灵活的结构。
6. 适配器模式(Adapter)
应用场景 :将一个类的接口转换为客户端期望的另一个接口(如旧系统接口适配新框架)。
代码示例:
cpp
#include <iostream>
// 目标接口(客户端期望的接口)
class Target {
public:
virtual void request() = 0;
virtual ~Target() = default;
};
// 适配者(需要被适配的旧接口)
class Adaptee {
public:
void specificRequest() {
std::cout << "Adaptee's specific request" << std::endl;
}
};
// 类适配器(继承适配者和目标接口)
class ClassAdapter : public Target, private Adaptee {
public:
void request() override {
specificRequest(); // 调用适配者的方法
}
};
// 对象适配器(持有适配者实例)
class ObjectAdapter : public Target {
private:
Adaptee* adaptee;
public:
ObjectAdapter(Adaptee* a) : adaptee(a) {}
void request() override {
adaptee->specificRequest();
}
};
int main() {
Target* adapter1 = new ClassAdapter();
adapter1->request(); // 输出:Adaptee's specific request
Adaptee adaptee;
Target* adapter2 = new ObjectAdapter(&adaptee);
adapter2->request(); // 输出:Adaptee's specific request
delete adapter1;
delete adapter2;
return 0;
}
注意事项:
- 类适配器通过继承实现,灵活性低;对象适配器通过组合实现,更推荐。
- 避免过度使用,优先考虑接口设计的一致性。
7. 桥接模式(Bridge)
应用场景 :分离抽象与实现,使两者可独立变化(如跨平台图形库:形状抽象与不同平台的绘制实现分离)。
代码示例:
cpp
#include <iostream>
#include <string>
// 实现部分接口
class DrawAPI {
public:
virtual void drawCircle(float x, float y, float radius) = 0;
virtual ~DrawAPI() = default;
};
// 具体实现A:OpenGL绘制
class OpenGLDraw : public DrawAPI {
public:
void drawCircle(float x, float y, float radius) override {
std::cout << "OpenGL Draw Circle: (" << x << "," << y << "), radius=" << radius << std::endl;
}
};
// 具体实现B:DirectX绘制
class DirectXDraw : public DrawAPI {
public:
void drawCircle(float x, float y, float radius) override {
std::cout << "DirectX Draw Circle: (" << x << "," << y << "), radius=" << radius << std::endl;
}
};
// 抽象部分
class Shape {
protected:
DrawAPI* drawAPI; // 桥接:持有实现部分的引用
public:
Shape(DrawAPI* api) : drawAPI(api) {}
virtual ~Shape() = default;
virtual void draw() = 0;
};
// 具体抽象:圆形
class Circle : public Shape {
private:
float x, y, radius;
public:
Circle(float x, float y, float r, DrawAPI* api)
: Shape(api), x(x), y(y), radius(r) {}
void draw() override {
drawAPI->drawCircle(x, y, radius);
}
};
int main() {
// 桥接:圆形 + OpenGL绘制
Shape* circle1 = new Circle(10, 20, 5, new OpenGLDraw());
circle1->draw(); // 输出:OpenGL Draw Circle: (10,20), radius=5
// 桥接:圆形 + DirectX绘制
Shape* circle2 = new Circle(30, 40, 10, new DirectXDraw());
circle2->draw(); // 输出:DirectX Draw Circle: (30,40), radius=10
delete circle1;
delete circle2;
return 0;
}
注意事项:
- 抽象与实现分离后,两者可独立扩展(新增形状或绘制方式无需修改对方)。
- 适合多维度变化的场景(如"形状+颜色""平台+功能")。
8. 组合模式(Composite)
应用场景 :处理树形结构数据(如文件系统、UI组件树),使客户端统一对待单个对象和组合对象。
代码示例:
cpp
#include <iostream>
#include <vector>
#include <string>
// 抽象组件
class Component {
protected:
std::string name;
public:
Component(const std::string& n) : name(n) {}
virtual ~Component() = default;
virtual void add(Component* c) {} // 默认空实现(叶子节点不支持)
virtual void remove(Component* c) {}
virtual void display(int depth) const = 0; // 显示层级结构
};
// 叶子节点:文件
class File : public Component {
public:
File(const std::string& n) : Component(n) {}
void display(int depth) const override {
std::cout << std::string(depth, '-') << name << std::endl;
}
};
// 组合节点:文件夹
class Folder : public Component {
private:
std::vector<Component*> children;
public:
Folder(const std::string& n) : Component(n) {}
void add(Component* c) override {
children.push_back(c);
}
void remove(Component* c) override {
// 简化实现:不实际删除,仅演示
}
void display(int depth) const override {
std::cout << std::string(depth, '-') << name << " (Folder)" << std::endl;
// 递归显示子节点
for (auto child : children) {
child->display(depth + 2);
}
}
~Folder() override {
for (auto child : children) {
delete child;
}
}
};
int main() {
Folder* root = new Folder("Root");
root->add(new File("readme.txt"));
Folder* docs = new Folder("Documents");
docs->add(new File("resume.pdf"));
docs->add(new File("notes.docx"));
root->add(docs);
root->display(1);
// 输出:
// -Root (Folder)
// ---readme.txt
// ---Documents (Folder)
// -----resume.pdf
// -----notes.docx
delete root;
return 0;
}
注意事项:
- 需明确叶子节点和组合节点的职责,避免叶子节点实现不必要的方法(如
add
/remove
)。 - 递归操作时需注意栈溢出风险(深层树形结构)。
9. 装饰模式(Decorator)
应用场景 :动态给对象添加功能(如IO流包装、咖啡加配料),且避免继承导致的类爆炸。
代码示例:
cpp
#include <iostream>
#include <string>
// 抽象组件:咖啡
class Coffee {
public:
virtual std::string getDescription() const = 0;
virtual double cost() const = 0;
virtual ~Coffee() = default;
};
// 具体组件:黑咖啡
class Espresso : public Coffee {
public:
std::string getDescription() const override {
return "Espresso";
}
double cost() const override {
return 2.0;
}
};
// 装饰器基类(继承并持有组件)
class Decorator : public Coffee {
protected:
Coffee* coffee; // 被装饰的对象
public:
Decorator(Coffee* c) : coffee(c) {}
~Decorator() override { delete coffee; }
};
// 具体装饰器:牛奶
class Milk : public Decorator {
public:
Milk(Coffee* c) : Decorator(c) {}
std::string getDescription() const override {
return coffee->getDescription() + ", Milk";
}
double cost() const override {
return coffee->cost() + 0.5;
}
};
// 具体装饰器:糖
class Sugar : public Decorator {
public:
Sugar(Coffee* c) : Decorator(c) {}
std::string getDescription() const override {
return coffee->getDescription() + ", Sugar";
}
double cost() const override {
return coffee->cost() + 0.3;
}
};
int main() {
Coffee* coffee = new Espresso();
coffee = new Milk(coffee);
coffee = new Sugar(coffee);
std::cout << "Description: " << coffee->getDescription() << std::endl; // 输出:Espresso, Milk, Sugar
std::cout << "Cost: $" << coffee->cost() << std::endl; // 输出:$2.8
delete coffee;
return 0;
}
注意事项:
- 装饰器和被装饰对象必须实现同一接口。
- 避免多层装饰导致的复杂性(如调试困难)。
10. 外观模式(Facade)
应用场景 :为复杂子系统提供统一接口(如智能家居控制中心,统一控制灯光、空调、窗帘)。
代码示例:
cpp
#include <iostream>
// 子系统1:灯光
class Light {
public:
void turnOn() { std::cout << "Light is on" << std::endl; }
void turnOff() { std::cout << "Light is off" << std::endl; }
};
// 子系统2:空调
class AirConditioner {
public:
void start() { std::cout << "AC is running" << std::endl; }
void stop() { std::cout << "AC is stopped" << std::endl; }
};
// 外观类:智能家居控制中心
class SmartHomeFacade {
private:
Light light;
AirConditioner ac;
public:
// 统一接口:离家模式
void leaveHome() {
light.turnOff();
ac.stop();
std::cout << "Leaving home, all devices off" << std::endl;
}
// 统一接口:回家模式
void arriveHome() {
light.turnOn();
ac.start();
std::cout << "Welcome home, devices activated" << std::endl;
}
};
int main() {
SmartHomeFacade home;
home.arriveHome();
// 输出:
// Light is on
// AC is running
// Welcome home, devices activated
home.leaveHome();
// 输出:
// Light is off
// AC is stopped
// Leaving home, all devices off
return 0;
}
注意事项:
- 外观模式不封装子系统,客户端仍可直接访问子系统(灵活性)。
- 避免外观类过于庞大,可拆分多个外观类。
11. 享元模式(Flyweight)
应用场景 :大量相似对象占用内存(如游戏中的树木、文字处理中的字符),通过共享对象减少内存消耗。
代码示例:
cpp
#include <iostream>
#include <unordered_map>
#include <string>
// 享元类:树的共享属性
class TreeType {
private:
std::string name; // 树种(如松树、橡树)
std::string color;
public:
TreeType(std::string n, std::string c) : name(n), color(c) {}
void draw(int x, int y) const { // x,y是非共享的外部状态
std::cout << "Draw " << name << " (color: " << color
<< ") at (" << x << "," << y << ")" << std::endl;
}
};
// 享元工厂:管理共享对象
class TreeTypeFactory {
private:
std::unordered_map<std::string, TreeType*> types; // 缓存池
public:
TreeType* getTreeType(const std::string& name, const std::string& color) {
std::string key = name + "_" + color;
if (types.find(key) == types.end()) {
types[key] = new TreeType(name, color); // 不存在则创建
}
return types[key]; // 返回共享对象
}
~TreeTypeFactory() {
for (auto& pair : types) {
delete pair.second;
}
}
};
// 树对象(包含共享和非共享状态)
class Tree {
private:
int x, y; // 非共享状态:位置
TreeType* type; // 共享状态
public:
Tree(int x, int y, TreeType* t) : x(x), y(y), type(t) {}
void draw() const {
type->draw(x, y);
}
};
int main() {
TreeTypeFactory factory;
// 共享同一棵树的类型
Tree* tree1 = new Tree(10, 20, factory.getTreeType("Pine", "Green"));
Tree* tree2 = new Tree(30, 40, factory.getTreeType("Pine", "Green"));
Tree* tree3 = new Tree(50, 60, factory.getTreeType("Oak", "Brown"));
tree1->draw(); // 输出:Draw Pine (color: Green) at (10,20)
tree2->draw(); // 输出:Draw Pine (color: Green) at (30,40)
tree3->draw(); // 输出:Draw Oak (color: Brown) at (50,60)
delete tree1;
delete tree2;
delete tree3;
return 0;
}
注意事项:
- 区分内部状态(可共享)和外部状态(不可共享,需客户端传入)。
- 适合对象数量庞大且相似性高的场景,否则可能增加复杂度。
12. 代理模式(Proxy)
应用场景 :控制对对象的访问(如远程代理、延迟加载、权限控制)。
代码示例:
cpp
#include <iostream>
#include <string>
// 抽象主题:图片
class Image {
public:
virtual void display() = 0;
virtual ~Image() = default;
};
// 真实主题:高清图片(加载成本高)
class HighResImage : public Image {
private:
std::string filename;
void loadFromDisk() { // 模拟耗时加载
std::cout << "Loading " << filename << " from disk..." << std::endl;
}
public:
HighResImage(const std::string& fn) : filename(fn) {
loadFromDisk(); // 构造时加载
}
void display() override {
std::cout << "Displaying " << filename << std::endl;
}
};
// 代理:延迟加载代理(需要时才加载真实图片)
class ImageProxy : public Image {
private:
std::string filename;
HighResImage* realImage; // 真实对象(延迟初始化)
public:
ImageProxy(const std::string& fn) : filename(fn), realImage(nullptr) {}
void display() override {
if (realImage == nullptr) {
realImage = new HighResImage(filename); // 需要时才加载
}
realImage->display();
}
~ImageProxy() override {
delete realImage;
}
};
int main() {
Image* image = new ImageProxy("photo.jpg");
std::cout << "Image created, not loaded yet" << std::endl;
// 首次显示时才加载
image->display();
// 输出:
// Loading photo.jpg from disk...
// Displaying photo.jpg
// 再次显示,无需重新加载
image->display(); // 输出:Displaying photo.jpg
delete image;
return 0;
}
注意事项:
- 代理与真实对象需实现同一接口,保证透明性。
- 避免过度使用,简单场景直接访问对象更高效。
三、行为型模式(11种)
行为型模式关注对象间的交互与职责分配。
13. 职责链模式(Chain of Responsibility)
应用场景 :请求需要多个对象处理,且处理者不确定(如日志级别过滤、事件冒泡)。
代码示例:
cpp
#include <iostream>
#include <string>
// 抽象处理者
class Logger {
protected:
Logger* next; // 下一个处理者
int level; // 处理级别
public:
Logger(int l, Logger* n) : level(l), next(n) {}
virtual ~Logger() { delete next; }
void log(int msgLevel, const std::string& message) {
if (msgLevel >= level) {
write(message); // 当前处理者处理
}
if (next != nullptr) {
next->log(msgLevel, message); // 传递给下一个
}
}
virtual void write(const std::string& message) = 0;
};
// 具体处理者:控制台日志(级别1)
class ConsoleLogger : public Logger {
public:
ConsoleLogger(int l, Logger* n) : Logger(l, n) {}
void write(const std::string& message) override {
std::cout << "Console: " << message << std::endl;
}
};
// 具体处理者:文件日志(级别2)
class FileLogger : public Logger {
public:
FileLogger(int l, Logger* n) : Logger(l, n) {}
void write(const std::string& message) override {
std::cout << "File: " << message << std::endl;
}
};
// 具体处理者:数据库日志(级别3)
class DatabaseLogger : public Logger {
public:
DatabaseLogger(int l, Logger* n) : Logger(l, n) {}
void write(const std::string& message) override {
std::cout << "Database: " << message << std::endl;
}
};
int main() {
// 构建职责链:Database -> File -> Console
Logger* logger = new DatabaseLogger(3,
new FileLogger(2,
new ConsoleLogger(1, nullptr)));
logger->log(1, "Debug message"); // 仅Console处理
// 输出:Console: Debug message
logger->log(2, "Warning message"); // File和Console处理
// 输出:
// File: Warning message
// Console: Warning message
delete logger;
return 0;
}
注意事项:
- 请求可能未被任何处理者处理,需考虑默认处理机制。
- 链的构建由客户端负责,需避免过长的链导致性能问题。
14. 命令模式(Command)
应用场景 :将请求封装为对象(如菜单操作、撤销/重做功能、任务队列)。
代码示例:
cpp
#include <iostream>
#include <vector>
#include <string>
// 接收者:灯
class Light {
private:
std::string location;
public:
Light(std::string loc) : location(loc) {}
void on() { std::cout << location << " Light is on" << std::endl; }
void off() { std::cout << location << " Light is off" << std::endl; }
};
// 抽象命令
class Command {
public:
virtual void execute() = 0;
virtual void undo() = 0;
virtual ~Command() = default;
};
// 具体命令:开灯
class LightOnCommand : public Command {
private:
Light* light;
public:
LightOnCommand(Light* l) : light(l) {}
void execute() override { light->on(); }
void undo() override { light->off(); } // 撤销:关灯
};
// 具体命令:关灯
class LightOffCommand : public Command {
private:
Light* light;
public:
LightOffCommand(Light* l) : light(l) {}
void execute() override { light->off(); }
void undo() override { light->on(); } // 撤销:开灯
};
// 调用者:遥控器
class RemoteControl {
private:
Command* onCommand;
Command* offCommand;
Command* lastCommand; // 记录最后执行的命令(用于撤销)
public:
void setCommands(Command* on, Command* off) {
onCommand = on;
offCommand = off;
}
void pressOn() {
onCommand->execute();
lastCommand = onCommand;
}
void pressOff() {
offCommand->execute();
lastCommand = offCommand;
}
void pressUndo() {
if (lastCommand != nullptr) {
lastCommand->undo();
}
}
};
int main() {
Light* livingRoomLight = new Light("Living Room");
Command* lightOn = new LightOnCommand(livingRoomLight);
Command* lightOff = new LightOffCommand(livingRoomLight);
RemoteControl remote;
remote.setCommands(lightOn, lightOff);
remote.pressOn(); // 输出:Living Room Light is on
remote.pressOff(); // 输出:Living Room Light is off
remote.pressUndo(); // 输出:Living Room Light is on(撤销关灯)
delete lightOn;
delete lightOff;
delete livingRoomLight;
return 0;
}
注意事项:
- 命令对象可能持有接收者引用,需注意生命周期管理。
- 适合需要日志记录、事务回滚的场景。
15. 解释器模式(Interpreter)
应用场景 :解析特定语法规则的语言(如简单表达式解析、正则表达式引擎)。
代码示例:
cpp
#include <iostream>
#include <string>
#include <memory>
// 抽象表达式
class Expression {
public:
virtual int interpret() = 0;
virtual ~Expression() = default;
};
// 终结符表达式:数字
class Number : public Expression {
private:
int value;
public:
Number(int v) : value(v) {}
int interpret() override { return value; }
};
// 非终结符表达式:加法
class Add : public Expression {
private:
std::unique_ptr<Expression> left;
std::unique_ptr<Expression> right;
public:
Add(Expression* l, Expression* r)
: left(l), right(r) {}
int interpret() override {
return left->interpret() + right->interpret();
}
};
// 非终结符表达式:乘法
class Multiply : public Expression {
private:
std::unique_ptr<Expression> left;
std::unique_ptr<Expression> right;
public:
Multiply(Expression* l, Expression* r)
: left(l), right(r) {}
int interpret() override {
return left->interpret() * right->interpret();
}
};
int main() {
// 解析表达式:(3 + 4) * 5
Expression* expr = new Multiply(
new Add(new Number(3), new Number(4)),
new Number(5)
);
std::cout << "Result: " << expr->interpret() << std::endl; // 输出:35
delete expr;
return 0;
}
注意事项:
- 适合简单语法,复杂语法会导致表达式类爆炸(如支持减法、除法等)。
- 可结合语法分析器生成工具(如ANTLR)使用。
16. 迭代器模式(Iterator)
应用场景 :遍历聚合对象(如容器),且不暴露其内部结构(C++ STL的std::iterator
是典型实现)。
代码示例:
cpp
#include <iostream>
#include <string>
// 前向声明
template <typename T>
class Iterator;
// 抽象聚合
template <typename T>
class Aggregate {
public:
virtual Iterator<T>* createIterator() = 0;
virtual int getSize() = 0;
virtual T getItem(int index) = 0;
virtual ~Aggregate() = default;
};
// 抽象迭代器
template <typename T>
class Iterator {
public:
virtual bool hasNext() = 0;
virtual T next() = 0;
virtual ~Iterator() = default;
};
// 具体聚合:数组
template <typename T>
class ArrayAggregate : public Aggregate<T> {
private:
T* items;
int size;
public:
ArrayAggregate(T* arr, int s) : items(arr), size(s) {}
Iterator<T>* createIterator() override;
int getSize() override { return size; }
T getItem(int index) override { return items[index]; }
};
// 具体迭代器:数组迭代器
template <typename T>
class ArrayIterator : public Iterator<T> {
private:
ArrayAggregate<T>* aggregate;
int index;
public:
ArrayIterator(ArrayAggregate<T>* a) : aggregate(a), index(0) {}
bool hasNext() override {
return index < aggregate->getSize();
}
T next() override {
return aggregate->getItem(index++);
}
};
// 实现聚合的createIterator
template <typename T>
Iterator<T>* ArrayAggregate<T>::createIterator() {
return new ArrayIterator<T>(this);
}
int main() {
std::string names[] = {"Alice", "Bob", "Charlie"};
ArrayAggregate<std::string> aggregate(names, 3);
Iterator<std::string>* it = aggregate.createIterator();
while (it->hasNext()) {
std::cout << it->next() << std::endl;
// 输出:Alice, Bob, Charlie
}
delete it;
return 0;
}
注意事项:
- C++ STL已提供完善的迭代器,无需重复实现。
- 迭代器应支持失效检测(如容器修改后迭代器失效)。
17. 中介者模式(Mediator)
应用场景 :多个对象相互依赖(如聊天室、GUI组件交互),通过中介者减少直接耦合。
代码示例:
cpp
#include <iostream>
#include <string>
#include <vector>
// 前向声明
class Colleague;
// 抽象中介者
class Mediator {
public:
virtual void send(const std::string& message, Colleague* sender) = 0;
virtual ~Mediator() = default;
};
// 抽象同事
class Colleague {
protected:
Mediator* mediator;
public:
Colleague(Mediator* m) : mediator(m) {}
virtual void send(const std::string& message) = 0;
virtual void receive(const std::string& message) = 0;
virtual ~Colleague() = default;
};
// 具体中介者:聊天室
class ChatRoom : public Mediator {
private:
std::vector<Colleague*> colleagues;
public:
void addColleague(Colleague* c) {
colleagues.push_back(c);
}
void send(const std::string& message, Colleague* sender) override {
// 转发消息给所有非发送者的同事
for (auto colleague : colleagues) {
if (colleague != sender) {
colleague->receive(message);
}
}
}
};
// 具体同事:用户
class User : public Colleague {
private:
std::string name;
public:
User(std::string n, Mediator* m) : Colleague(m), name(n) {}
void send(const std::string& message) override {
std::cout << name << " sends: " << message << std::endl;
mediator->send(message, this);
}
void receive(const std::string& message) override {
std::cout << name << " receives: " << message << std::endl;
}
};
int main() {
ChatRoom* chat = new ChatRoom();
User* alice = new User("Alice", chat);
User* bob = new User("Bob", chat);
chat->addColleague(alice);
chat->addColleague(bob);
alice->send("Hi Bob!");
// 输出:
// Alice sends: Hi Bob!
// Bob receives: Hi Bob!
bob->send("Hello Alice!");
// 输出:
// Bob sends: Hello Alice!
// Alice receives: Hello Alice!
delete alice;
delete bob;
delete chat;
return 0;
}
注意事项:
- 中介者可能成为"上帝类"(过度集中逻辑),需合理拆分。
- 适合交互复杂但规则固定的场景。
18. 备忘录模式(Memento)
应用场景 :保存对象状态以便后续恢复(如游戏存档、编辑器撤销功能)。
代码示例:
cpp
#include <iostream>
#include <string>
#include <vector>
// 备忘录:保存状态
class Memento {
private:
std::string state;
// 仅允许Originator访问构造函数
Memento(const std::string& s) : state(s) {}
friend class Originator;
public:
std::string getState() const { return state; }
};
// 原发器:创建并恢复备忘录
class Originator {
private:
std::string state;
public:
void setState(const std::string& s) {
std::cout << "Setting state to: " << s << std::endl;
state = s;
}
Memento* saveToMemento() {
return new Memento(state);
}
void restoreFromMemento(Memento* m) {
state = m->getState();
std::cout << "Restored state to: " << state << std::endl;
}
};
// 管理者:保存备忘录
class Caretaker {
private:
std::vector<Memento*> mementos;
public:
void addMemento(Memento* m) {
mementos.push_back(m);
}
Memento* getMemento(int index) {
return mementos[index];
}
~Caretaker() {
for (auto m : mementos) {
delete m;
}
}
};
int main() {
Originator originator;
Caretaker caretaker;
originator.setState("State 1");
caretaker.addMemento(originator.saveToMemento());
originator.setState("State 2");
caretaker.addMemento(originator.saveToMemento());
originator.setState("State 3");
// 恢复到State 1
originator.restoreFromMemento(caretaker.getMemento(0)); // 输出:Restored state to: State 1
return 0;
}
注意事项:
- 备忘录可能占用大量内存(如频繁保存大对象状态)。
- 需控制备忘录的访问权限(避免外部修改)。
19. 观察者模式(Observer)
应用场景 :对象状态变化时通知依赖它的其他对象(如发布-订阅模型、事件监听)。
代码示例:
cpp
#include <iostream>
#include <vector>
#include <string>
// 前向声明
class Subject;
// 抽象观察者
class Observer {
public:
virtual void update(Subject* subject) = 0;
virtual ~Observer() = default;
};
// 抽象主题
class Subject {
private:
std::vector<Observer*> observers;
public:
void attach(Observer* o) {
observers.push_back(o);
}
void detach(Observer* o) {
// 简化实现:不实际删除
}
void notify() {
for (auto observer : observers) {
observer->update(this);
}
}
virtual std::string getState() = 0;
virtual void setState(const std::string& s) = 0;
};
// 具体主题:报纸
class Newspaper : public Subject {
private:
std::string news;
public:
std::string getState() override { return news; }
void setState(const std::string& s) override {
news = s;
notify(); // 状态变化时通知观察者
}
};
// 具体观察者:读者
class Reader : public Observer {
private:
std::string name;
public:
Reader(std::string n) : name(n) {}
void update(Subject* subject) override {
std::cout << name << " received news: " << subject->getState() << std::endl;
}
};
int main() {
Newspaper newspaper;
Reader alice("Alice");
Reader bob("Bob");
newspaper.attach(&alice);
newspaper.attach(&bob);
newspaper.setState("Breaking News: Design Patterns!");
// 输出:
// Alice received news: Breaking News: Design Patterns!
// Bob received news: Breaking News: Design Patterns!
return 0;
}
注意事项:
- 需处理观察者的生命周期(避免通知已销毁的观察者)。
- 可支持观察者选择感兴趣的事件类型(过滤通知)。
20. 状态模式(State)
应用场景 :对象状态变化时行为随之改变(如订单状态流转、电梯运行状态)。
代码示例:
cpp
#include <iostream>
#include <string>
// 前向声明
class Context;
// 抽象状态
class State {
public:
virtual void handle(Context* context) = 0;
virtual std::string getName() = 0;
virtual ~State() = default;
};
// 具体状态:已下单
class OrderedState : public State {
public:
void handle(Context* context) override;
std::string getName() override { return "Ordered"; }
};
// 具体状态:已付款
class PaidState : public State {
public:
void handle(Context* context) override;
std::string getName() override { return "Paid"; }
};
// 具体状态:已发货
class ShippedState : public State {
public:
void handle(Context* context) override;
std::string getName() override { return "Shipped"; }
};
// 上下文:订单
class Context {
private:
State* currentState;
public:
Context() {
currentState = new OrderedState(); // 初始状态
std::cout << "Order state: " << currentState->getName() << std::endl;
}
void setState(State* s) {
delete currentState;
currentState = s;
std::cout << "Order state changed to: " << currentState->getName() << std::endl;
}
void nextState() {
currentState->handle(this);
}
~Context() {
delete currentState;
}
};
// 实现状态转换逻辑
void OrderedState::handle(Context* context) {
context->setState(new PaidState());
}
void PaidState::handle(Context* context) {
context->setState(new ShippedState());
}
void ShippedState::handle(Context* context) {
std::cout << "Order already shipped, no next state" << std::endl;
}
int main() {
Context order;
order.nextState(); // 已下单 -> 已付款
order.nextState(); // 已付款 -> 已发货
order.nextState(); // 已发货(无后续状态)
// 输出:
// Order state: Ordered
// Order state changed to: Paid
// Order state changed to: Shipped
// Order already shipped, no next state
return 0;
}
注意事项:
- 状态转换逻辑集中在状态类中,避免上下文类中出现大量
if-else
。 - 适合状态数量固定且转换规则明确的场景。
21. 策略模式(Strategy)
应用场景 :多种算法可选(如排序算法、支付方式),需动态切换且避免if-else
判断。
代码示例:
cpp
#include <iostream>
#include <string>
// 抽象策略:支付方式
class PaymentStrategy {
public:
virtual void pay(double amount) = 0;
virtual ~PaymentStrategy() = default;
};
// 具体策略:信用卡支付
class CreditCardPayment : public PaymentStrategy {
private:
std::string cardNumber;
public:
CreditCardPayment(std::string num) : cardNumber(num) {}
void pay(double amount) override {
std::cout << "Paid $" << amount << " with Credit Card: " << cardNumber << std::endl;
}
};
// 具体策略:支付宝支付
class AlipayPayment : public PaymentStrategy {
private:
std::string username;
public:
AlipayPayment(std::string name) : username(name) {}
void pay(double amount) override {
std::cout << "Paid $" << amount << " with Alipay: " << username << std::endl;
}
};
// 上下文:购物车
class ShoppingCart {
private:
PaymentStrategy* paymentStrategy;
public:
void setPaymentStrategy(PaymentStrategy* s) {
paymentStrategy = s;
}
void checkout(double amount) {
paymentStrategy->pay(amount);
}
};
int main() {
ShoppingCart cart;
// 使用信用卡支付
cart.setPaymentStrategy(new CreditCardPayment("1234-5678-9012"));
cart.checkout(99.99); // 输出:Paid $99.99 with Credit Card: 1234-5678-9012
// 切换为支付宝支付
cart.setPaymentStrategy(new AlipayPayment("user@example.com"));
cart.checkout(49.99); // 输出:Paid $49.99 with Alipay: user@example.com
return 0;
}
注意事项:
- 客户端需知道所有策略类,以便选择合适的策略。
- 策略间应无状态,可共享实例(如使用单例)。
22. 模板方法模式(Template Method)
应用场景 :算法骨架固定,但部分步骤可变(如流程化任务:数据处理、游戏角色升级)。
代码示例:
cpp
#include <iostream>
#include <string>
// 抽象类:定义模板方法
class DataProcessor {
public:
// 模板方法:固定算法骨架
void process() {
readData();
analyzeData();
writeReport();
}
virtual ~DataProcessor() = default;
protected:
// 抽象步骤(子类实现)
virtual void readData() = 0;
virtual void analyzeData() = 0;
// 具体步骤(父类实现,可选)
void writeReport() {
std::cout << "Generating standard report..." << std::endl;
}
};
// 具体子类:处理CSV数据
class CsvProcessor : public DataProcessor {
protected:
void readData() override {
std::cout << "Reading data from CSV file" << std::endl;
}
void analyzeData() override {
std::cout << "Analyzing CSV data" << std::endl;
}
};
// 具体子类:处理数据库数据
class DbProcessor : public DataProcessor {
protected:
void readData() override {
std::cout << "Reading data from database" << std::endl;
}
void analyzeData() override {
std::cout << "Analyzing database data" << std::endl;
}
// 重写钩子方法(可选)
void writeReport() override {
std::cout << "Generating database-specific report..." << std::endl;
}
};
int main() {
DataProcessor* csv = new CsvProcessor();
csv->process();
// 输出:
// Reading data from CSV file
// Analyzing CSV data
// Generating standard report...
DataProcessor* db = new DbProcessor();
db->process();
// 输出:
// Reading data from database
// Analyzing database data
// Generating database-specific report...
delete csv;
delete db;
return 0;
}
注意事项:
- 模板方法通常声明为
final
,防止子类重写算法骨架。 - 钩子方法(
hook
)可让子类选择性扩展步骤。
23. 访问者模式(Visitor)
应用场景 :为复杂对象结构(如组合模式的树形结构)添加新操作,且不修改对象类(如文档导出、数据统计)。
代码示例:
cpp
#include <iostream>
#include <string>
#include <vector>
// 前向声明
class ElementA;
class ElementB;
// 抽象访问者
class Visitor {
public:
virtual void visit(ElementA* element) = 0;
virtual void visit(ElementB* element) = 0;
virtual ~Visitor() = default;
};
// 抽象元素
class Element {
public:
virtual void accept(Visitor* visitor) = 0; // 接受访问者
virtual ~Element() = default;
};
// 具体元素A
class ElementA : public Element {
private:
std::string data;
public:
ElementA(std::string d) : data(d) {}
std::string getData() const { return data; }
void accept(Visitor* visitor) override {
visitor->visit(this); // 调用访问者的对应方法
}
};
// 具体元素B
class ElementB : public Element {
private:
int value;
public:
ElementB(int v) : value(v) {}
int getValue() const { return value; }
void accept(Visitor* visitor) override {
visitor->visit(this);
}
};
// 对象结构:管理元素集合
class ObjectStructure {
private:
std::vector<Element*> elements;
public:
void addElement(Element* e) {
elements.push_back(e);
}
void accept(Visitor* visitor) {
for (auto e : elements) {
e->accept(visitor);
}
}
~ObjectStructure() {
for (auto e : elements) {
delete e;
}
}
};
// 具体访问者:打印访问者
class PrintVisitor : public Visitor {
public:
void visit(ElementA* element) override {
std::cout << "ElementA data: " << element->getData() << std::endl;
}
void visit(ElementB* element) override {
std::cout << "ElementB value: " << element->getValue() << std::endl;
}
};
// 具体访问者:计算访问者(对ElementB求和)
class SumVisitor : public Visitor {
private:
int sum = 0;
public:
void visit(ElementA* element) override {
// 不处理ElementA
}
void visit(ElementB* element) override {
sum += element->getValue();
}
int getSum() const { return sum; }
};
int main() {
ObjectStructure structure;
structure.addElement(new ElementA("Hello"));
structure.addElement(new ElementB(10));
structure.addElement(new ElementB(20));
// 打印元素
PrintVisitor printVisitor;
structure.accept(&printVisitor);
// 输出:
// ElementA data: Hello
// ElementB value: 10
// ElementB value: 20
// 计算ElementB的和
SumVisitor sumVisitor;
structure.accept(&sumVisitor);
std::cout << "Sum of ElementB values: " << sumVisitor.getSum() << std::endl; // 输出:30
return 0;
}
注意事项:
- 元素类新增时,需修改所有访问者类,违反开闭原则。
- 适合元素结构稳定,但操作频繁变化的场景。
总结
设计模式的核心是"解耦"和"复用",选择模式时需结合具体场景,避免过度设计。实际开发中,应优先使用C++标准库或成熟框架中已实现的模式(如STL的迭代器、智能指针的RAII模式),而非重复造轮子。