设计模式详解
本文档详细讲解120天计划中涉及的7种设计模式,包括定义、应用场景、代码实现和实际案例。
目录
- 一、创建型模式
- [1. 单例模式](#1. 单例模式 "#1-%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F")
- [2. 工厂模式](#2. 工厂模式 "#2-%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F")
- 二、结构型模式
- [3. 适配器模式](#3. 适配器模式 "#3-%E9%80%82%E9%85%8D%E5%99%A8%E6%A8%A1%E5%BC%8F")
- [4. 装饰器模式](#4. 装饰器模式 "#4-%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F")
- 三、行为型模式
- [5. 观察者模式](#5. 观察者模式 "#5-%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F")
- [6. 策略模式](#6. 策略模式 "#6-%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F")
- [7. 状态机模式](#7. 状态机模式 "#7-%E7%8A%B6%E6%80%81%E6%9C%BA%E6%A8%A1%E5%BC%8F")
- [8. 责任链模式](#8. 责任链模式 "#8-%E8%B4%A3%E4%BB%BB%E9%93%BE%E6%A8%A1%E5%BC%8F")
- [9. 模板模式](#9. 模板模式 "#9-%E6%A8%A1%E6%9D%BF%E6%A8%A1%E5%BC%8F")
- 四、设计模式对比总结
一、创建型模式
1. 单例模式
1.1 模式定义
单例模式(Singleton Pattern):确保一个类只有一个实例,并提供一个全局访问点。
1.2 核心思想
- 私有化构造函数,防止外部创建实例
- 提供静态方法获取唯一实例
- 内部维护唯一实例
1.3 应用场景
| 场景 |
说明 |
| 配置管理器 |
应用程序只需要一个配置对象 |
| 日志记录器 |
统一的日志输出管理 |
| 数据库连接池 |
管理有限的数据库连接 |
| 线程池 |
管理线程资源 |
| 缓存系统 |
全局缓存管理 |
1.4 代码实现
方式一:懒汉式(线程不安全)
cpp
复制代码
class Singleton {
private:
static Singleton* instance;
// 私有构造函数
Singleton() {}
public:
// 删除拷贝构造和赋值操作
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
// 获取实例
static Singleton* getInstance() {
if (instance == nullptr) {
instance = new Singleton();
}
return instance;
}
};
// 初始化静态成员
Singleton* Singleton::instance = nullptr;
问题:多线程环境下可能创建多个实例。
方式二:懒汉式(线程安全)
cpp
复制代码
#include <mutex>
class Singleton {
private:
static Singleton* instance;
static std::mutex mtx;
Singleton() {}
public:
static Singleton* getInstance() {
// 双重检查锁定
if (instance == nullptr) {
std::lock_guard<std::mutex> lock(mtx);
if (instance == nullptr) {
instance = new Singleton();
}
}
return instance;
}
};
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mtx;
方式三:饿汉式
cpp
复制代码
class Singleton {
private:
static Singleton instance;
Singleton() {}
public:
static Singleton& getInstance() {
return instance;
}
};
// 程序启动时就创建实例
Singleton Singleton::instance;
方式四:现代C++11最佳实践(推荐)
cpp
复制代码
class Singleton {
private:
Singleton() {}
public:
// 删除拷贝和赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
// C++11保证静态局部变量初始化的线程安全性
static Singleton& getInstance() {
static Singleton instance;
return instance;
}
void doSomething() {
std::cout << "Singleton working..." << std::endl;
}
};
// 使用
int main() {
Singleton& s = Singleton::getInstance();
s.doSomething();
return 0;
}
1.5 优缺点
| 优点 |
缺点 |
| 保证唯一实例 |
没有抽象层,扩展困难 |
| 全局访问点 |
违反单一职责原则 |
| 延迟初始化 |
滥用会导致代码耦合度高 |
| 节省资源 |
测试困难 |
1.6 实际应用案例
cpp
复制代码
// 日志管理器示例
class Logger {
private:
std::ofstream logFile;
Logger() {
logFile.open("app.log", std::ios::app);
}
public:
static Logger& getInstance() {
static Logger instance;
return instance;
}
void log(const std::string& message) {
auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
logFile << "[" << std::ctime(&time) << "] " << message << std::endl;
}
};
// 使用
Logger::getInstance().log("Application started");
2. 工厂模式
2.1 模式定义
工厂模式(Factory Pattern):定义一个创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类。
2.2 三种形式
| 类型 |
说明 |
| 简单工厂 |
一个工厂类根据参数创建不同产品 |
| 工厂方法 |
每个产品有对应的工厂子类 |
| 抽象工厂 |
创建一系列相关的产品 |
2.3 应用场景
- 日志记录器:文件日志、数据库日志、控制台日志
- 数据库连接:MySQL、PostgreSQL、SQLite
- 支付方式:支付宝、微信、银行卡
- 消息发送:邮件、短信、推送
2.4 代码实现
简单工厂模式
cpp
复制代码
#include <iostream>
#include <string>
#include <memory>
// 产品接口
class Product {
public:
virtual ~Product() {}
virtual void use() = 0;
};
// 具体产品A
class ProductA : public Product {
public:
void use() override {
std::cout << "Using Product A" << std::endl;
}
};
// 具体产品B
class ProductB : public Product {
public:
void use() override {
std::cout << "Using Product B" << std::endl;
}
};
// 简单工厂
class SimpleFactory {
public:
enum ProductType { TYPE_A, TYPE_B };
static std::unique_ptr<Product> createProduct(ProductType type) {
switch (type) {
case TYPE_A:
return std::make_unique<ProductA>();
case TYPE_B:
return std::make_unique<ProductB>();
default:
return nullptr;
}
}
};
// 使用
int main() {
auto productA = SimpleFactory::createProduct(SimpleFactory::TYPE_A);
productA->use();
auto productB = SimpleFactory::createProduct(SimpleFactory::TYPE_B);
productB->use();
return 0;
}
工厂方法模式
cpp
复制代码
#include <iostream>
#include <memory>
// 产品接口
class Product {
public:
virtual ~Product() {}
virtual void use() = 0;
};
// 具体产品
class ProductA : public Product {
public:
void use() override {
std::cout << "Using Product A" << std::endl;
}
};
class ProductB : public Product {
public:
void use() override {
std::cout << "Using Product B" << std::endl;
}
};
// 工厂接口
class Factory {
public:
virtual ~Factory() {}
virtual std::unique_ptr<Product> createProduct() = 0;
};
// 具体工厂A
class FactoryA : public Factory {
public:
std::unique_ptr<Product> createProduct() override {
return std::make_unique<ProductA>();
}
};
// 具体工厂B
class FactoryB : public Factory {
public:
std::unique_ptr<Product> createProduct() override {
return std::make_unique<ProductB>();
}
};
// 使用
int main() {
std::unique_ptr<Factory> factoryA = std::make_unique<FactoryA>();
auto productA = factoryA->createProduct();
productA->use();
std::unique_ptr<Factory> factoryB = std::make_unique<FactoryB>();
auto productB = factoryB->createProduct();
productB->use();
return 0;
}
抽象工厂模式
cpp
复制代码
#include <iostream>
#include <memory>
// 产品族:按钮
class Button {
public:
virtual ~Button() {}
virtual void render() = 0;
};
class WindowsButton : public Button {
public:
void render() override {
std::cout << "Windows Button" << std::endl;
}
};
class LinuxButton : public Button {
public:
void render() override {
std::cout << "Linux Button" << std::endl;
}
};
// 产品族:文本框
class TextBox {
public:
virtual ~TextBox() {}
virtual void render() = 0;
};
class WindowsTextBox : public TextBox {
public:
void render() override {
std::cout << "Windows TextBox" << std::endl;
}
};
class LinuxTextBox : public TextBox {
public:
void render() override {
std::cout << "Linux TextBox" << std::endl;
}
};
// 抽象工厂
class GUIFactory {
public:
virtual ~GUIFactory() {}
virtual std::unique_ptr<Button> createButton() = 0;
virtual std::unique_ptr<TextBox> createTextBox() = 0;
};
// Windows工厂
class WindowsFactory : public GUIFactory {
public:
std::unique_ptr<Button> createButton() override {
return std::make_unique<WindowsButton>();
}
std::unique_ptr<TextBox> createTextBox() override {
return std::make_unique<WindowsTextBox>();
}
};
// Linux工厂
class LinuxFactory : public GUIFactory {
public:
std::unique_ptr<Button> createButton() override {
return std::make_unique<LinuxButton>();
}
std::unique_ptr<TextBox> createTextBox() override {
return std::make_unique<LinuxTextBox>();
}
};
// 使用
int main() {
std::unique_ptr<GUIFactory> factory = std::make_unique<WindowsFactory>();
auto button = factory->createButton();
auto textBox = factory->createTextBox();
button->render();
textBox->render();
return 0;
}
2.5 优缺点
| 优点 |
缺点 |
| 解耦客户端和具体产品 |
增加类的数量 |
| 符合开闭原则 |
增加系统复杂度 |
| 符合单一职责原则 |
简单工厂违反开闭原则 |
| 便于扩展新产品 |
|
2.6 实际应用案例
cpp
复制代码
// 数据库连接工厂
class Database {
public:
virtual ~Database() {}
virtual void connect() = 0;
virtual void query(const std::string& sql) = 0;
};
class MySQL : public Database {
public:
void connect() override {
std::cout << "Connecting to MySQL..." << std::endl;
}
void query(const std::string& sql) override {
std::cout << "MySQL executing: " << sql << std::endl;
}
};
class PostgreSQL : public Database {
public:
void connect() override {
std::cout << "Connecting to PostgreSQL..." << std::endl;
}
void query(const std::string& sql) override {
std::cout << "PostgreSQL executing: " << sql << std::endl;
}
};
class DatabaseFactory {
public:
enum DBType { MYSQL, POSTGRESQL };
static std::unique_ptr<Database> createDatabase(DBType type) {
switch (type) {
case MYSQL:
return std::make_unique<MySQL>();
case POSTGRESQL:
return std::make_unique<PostgreSQL>();
default:
return nullptr;
}
}
};
// 使用
int main() {
auto db = DatabaseFactory::createDatabase(DatabaseFactory::MYSQL);
db->connect();
db->query("SELECT * FROM users");
return 0;
}
二、结构型模式
3. 适配器模式
3.1 模式定义
适配器模式(Adapter Pattern):将一个类的接口转换成客户期望的另一个接口,使原本接口不兼容的类可以一起工作。
3.2 两种实现方式
| 方式 |
说明 |
| 类适配器 |
通过多重继承实现 |
| 对象适配器 |
通过组合实现(推荐) |
3.3 应用场景
- 使用第三方库,接口不兼容
- 新旧系统整合
- 不同数据格式转换
- 复用现有类,但接口不符合需求
3.4 代码实现
对象适配器(推荐)
cpp
复制代码
#include <iostream>
#include <memory>
// 目标接口
class Target {
public:
virtual ~Target() {}
virtual void request() = 0;
};
// 被适配者(已有接口)
class Adaptee {
public:
void specificRequest() {
std::cout << "Adaptee: specificRequest()" << std::endl;
}
};
// 适配器
class Adapter : public Target {
private:
std::unique_ptr<Adaptee> adaptee;
public:
Adapter() : adaptee(std::make_unique<Adaptee>()) {}
void request() override {
// 转换调用
adaptee->specificRequest();
}
};
// 使用
int main() {
std::unique_ptr<Target> target = std::make_unique<Adapter>();
target->request();
return 0;
}
类适配器
cpp
复制代码
// 目标接口
class Target {
public:
virtual ~Target() {}
virtual void request() = 0;
};
// 被适配者
class Adaptee {
public:
void specificRequest() {
std::cout << "Adaptee: specificRequest()" << std::endl;
}
};
// 类适配器(多重继承)
class Adapter : public Target, private Adaptee {
public:
void request() override {
specificRequest();
}
};
3.5 实际应用案例
cpp
复制代码
#include <iostream>
#include <string>
#include <memory>
// 旧系统:XML解析器
class XMLParser {
public:
void parseXML(const std::string& xml) {
std::cout << "Parsing XML: " << xml << std::endl;
}
};
// 新系统:JSON解析接口
class JSONParser {
public:
virtual ~JSONParser() {}
virtual void parseJSON(const std::string& json) = 0;
};
// 适配器:让XML解析器支持JSON
class XMLToJSONAdapter : public JSONParser {
private:
std::unique_ptr<XMLParser> xmlParser;
std::string jsonToXML(const std::string& json) {
// 简化转换逻辑
return "<converted>" + json + "</converted>";
}
public:
XMLToJSONAdapter() : xmlParser(std::make_unique<XMLParser>()) {}
void parseJSON(const std::string& json) override {
std::string xml = jsonToXML(json);
xmlParser->parseXML(xml);
}
};
// 使用
int main() {
std::unique_ptr<JSONParser> parser = std::make_unique<XMLToJSONAdapter>();
parser->parseJSON("{\"name\": \"test\"}");
return 0;
}
3.6 优缺点
| 优点 |
缺点 |
| 复用现有类 |
过多使用会使系统凌乱 |
| 解耦客户端和被适配者 |
增加代码复杂度 |
| 符合开闭原则 |
|
| 透明性高 |
|
4. 装饰器模式
4.1 模式定义
装饰器模式(Decorator Pattern):动态地给对象添加一些额外的职责,比生成子类更为灵活。
4.2 核心思想
- 装饰器和被装饰对象有相同的接口
- 装饰器包含一个指向被装饰对象的引用
- 可以层层装饰
4.3 应用场景
- 咖啡店:基础咖啡 + 牛奶 + 糖 + 奶油
- 文本处理:基础文本 + 加粗 + 斜体 + 下划线
- 数据流:基础流 + 缓冲 + 加密 + 压缩
- UI组件:基础组件 + 边框 + 滚动条
4.4 代码实现
cpp
复制代码
#include <iostream>
#include <memory>
#include <string>
// 组件接口
class Component {
public:
virtual ~Component() {}
virtual std::string operation() const = 0;
};
// 具体组件
class ConcreteComponent : public Component {
public:
std::string operation() const override {
return "ConcreteComponent";
}
};
// 装饰器基类
class Decorator : public Component {
protected:
std::shared_ptr<Component> component;
public:
Decorator(std::shared_ptr<Component> comp) : component(comp) {}
};
// 具体装饰器A
class ConcreteDecoratorA : public Decorator {
public:
using Decorator::Decorator;
std::string operation() const override {
return "DecoratorA(" + component->operation() + ")";
}
};
// 具体装饰器B
class ConcreteDecoratorB : public Decorator {
public:
using Decorator::Decorator;
std::string operation() const override {
return "DecoratorB(" + component->operation() + ")";
}
};
// 使用
int main() {
// 创建基础组件
auto component = std::make_shared<ConcreteComponent>();
std::cout << "基础: " << component->operation() << std::endl;
// 添加装饰器A
auto decoratorA = std::make_shared<ConcreteDecoratorA>(component);
std::cout << "装饰A: " << decoratorA->operation() << std::endl;
// 再添加装饰器B
auto decoratorB = std::make_shared<ConcreteDecoratorB>(decoratorA);
std::cout << "装饰A+B: " << decoratorB->operation() << std::endl;
return 0;
}
4.5 实际应用案例:咖啡店
cpp
复制代码
#include <iostream>
#include <memory>
#include <string>
// 咖啡接口
class Coffee {
public:
virtual ~Coffee() {}
virtual std::string getDescription() const = 0;
virtual double getCost() const = 0;
};
// 基础咖啡
class SimpleCoffee : public Coffee {
public:
std::string getDescription() const override {
return "Simple Coffee";
}
double getCost() const override {
return 10.0;
}
};
// 咖啡装饰器基类
class CoffeeDecorator : public Coffee {
protected:
std::shared_ptr<Coffee> coffee;
public:
CoffeeDecorator(std::shared_ptr<Coffee> c) : coffee(c) {}
};
// 牛奶装饰器
class MilkDecorator : public CoffeeDecorator {
public:
using CoffeeDecorator::CoffeeDecorator;
std::string getDescription() const override {
return coffee->getDescription() + " + Milk";
}
double getCost() const override {
return coffee->getCost() + 3.0;
}
};
// 糖装饰器
class SugarDecorator : public CoffeeDecorator {
public:
using CoffeeDecorator::CoffeeDecorator;
std::string getDescription() const override {
return coffee->getDescription() + " + Sugar";
}
double getCost() const override {
return coffee->getCost() + 1.0;
}
};
// 奶油装饰器
class CreamDecorator : public CoffeeDecorator {
public:
using CoffeeDecorator::CoffeeDecorator;
std::string getDescription() const override {
return coffee->getDescription() + " + Cream";
}
double getCost() const override {
return coffee->getCost() + 5.0;
}
};
// 使用
int main() {
// 点一杯基础咖啡
auto coffee = std::make_shared<SimpleCoffee>();
std::cout << coffee->getDescription() << " - $" << coffee->getCost() << std::endl;
// 加牛奶
coffee = std::make_shared<MilkDecorator>(coffee);
std::cout << coffee->getDescription() << " - $" << coffee->getCost() << std::endl;
// 加糖
coffee = std::make_shared<SugarDecorator>(coffee);
std::cout << coffee->getDescription() << " - $" << coffee->getCost() << std::endl;
// 加奶油
coffee = std::make_shared<CreamDecorator>(coffee);
std::cout << coffee->getDescription() << " - $" << coffee->getCost() << std::endl;
return 0;
}
/*
输出:
Simple Coffee - $10
Simple Coffee + Milk - $13
Simple Coffee + Milk + Sugar - $14
Simple Coffee + Milk + Sugar + Cream - $19
*/
4.6 优缺点
| 优点 |
缺点 |
| 动态扩展功能 |
增加许多小对象 |
| 比继承更灵活 |
装饰器嵌套过多会复杂 |
| 符合开闭原则 |
难以追踪装饰顺序 |
| 可组合多个装饰器 |
|
三、行为型模式
5. 观察者模式
5.1 模式定义
观察者模式(Observer Pattern):定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
5.2 核心角色
| 角色 |
说明 |
| Subject(主题) |
被观察的对象,维护观察者列表 |
| Observer(观察者) |
定义更新接口 |
| ConcreteSubject |
具体主题,状态改变时通知观察者 |
| ConcreteObserver |
具体观察者,实现更新逻辑 |
5.3 应用场景
- 事件处理系统
- 消息订阅/发布
- GUI事件监听
- 股票价格监控
- 新闻推送
5.4 代码实现
cpp
复制代码
#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <algorithm>
// 观察者接口
class Observer {
public:
virtual ~Observer() {}
virtual void update(const std::string& message) = 0;
};
// 主题接口
class Subject {
public:
virtual ~Subject() {}
virtual void attach(std::shared_ptr<Observer> observer) = 0;
virtual void detach(std::shared_ptr<Observer> observer) = 0;
virtual void notify(const std::string& message) = 0;
};
// 具体主题
class ConcreteSubject : public Subject {
private:
std::vector<std::weak_ptr<Observer>> observers;
public:
void attach(std::shared_ptr<Observer> observer) override {
observers.push_back(observer);
}
void detach(std::shared_ptr<Observer> observer) override {
observers.erase(
std::remove_if(observers.begin(), observers.end(),
[&observer](const std::weak_ptr<Observer>& weakObs) {
auto obs = weakObs.lock();
return !obs || obs == observer;
}),
observers.end()
);
}
void notify(const std::string& message) override {
// 先清理已销毁的观察者
observers.erase(
std::remove_if(observers.begin(), observers.end(),
[](const std::weak_ptr<Observer>& weakObs) {
return weakObs.expired();
}),
observers.end()
);
// 通知所有观察者
for (auto& weakObs : observers) {
if (auto obs = weakObs.lock()) {
obs->update(message);
}
}
}
};
// 具体观察者
class ConcreteObserver : public Observer {
private:
std::string name;
public:
ConcreteObserver(const std::string& n) : name(n) {}
void update(const std::string& message) override {
std::cout << "[" << name << "] received: " << message << std::endl;
}
};
// 使用
int main() {
auto subject = std::make_shared<ConcreteSubject>();
auto observer1 = std::make_shared<ConcreteObserver>("Observer1");
auto observer2 = std::make_shared<ConcreteObserver>("Observer2");
auto observer3 = std::make_shared<ConcreteObserver>("Observer3");
subject->attach(observer1);
subject->attach(observer2);
subject->attach(observer3);
subject->notify("Hello Observers!");
subject->detach(observer2);
subject->notify("Observer2 removed");
return 0;
}
5.5 实际应用案例:新闻发布系统
cpp
复制代码
#include <iostream>
#include <vector>
#include <memory>
#include <string>
// 新闻观察者
class NewsObserver {
public:
virtual ~NewsObserver() {}
virtual void onNewsUpdate(const std::string& news) = 0;
};
// 新闻发布者
class NewsPublisher {
private:
std::vector<std::weak_ptr<NewsObserver>> subscribers;
public:
void subscribe(std::shared_ptr<NewsObserver> observer) {
subscribers.push_back(observer);
}
void unsubscribe(std::shared_ptr<NewsObserver> observer) {
// 简化实现
}
void publishNews(const std::string& news) {
std::cout << "\n=== 发布新闻: " << news << " ===" << std::endl;
for (auto& weakObs : subscribers) {
if (auto obs = weakObs.lock()) {
obs->onNewsUpdate(news);
}
}
}
};
// 手机客户端
class MobileClient : public NewsObserver {
private:
std::string userName;
public:
MobileClient(const std::string& name) : userName(name) {}
void onNewsUpdate(const std::string& news) override {
std::cout << "[手机-" << userName << "] 收到新闻: " << news << std::endl;
}
};
// 邮件客户端
class EmailClient : public NewsObserver {
private:
std::string email;
public:
EmailClient(const std::string& e) : email(e) {}
void onNewsUpdate(const std::string& news) override {
std::cout << "[邮件-" << email << "] 收到新闻: " << news << std::endl;
}
};
// 使用
int main() {
auto publisher = std::make_shared<NewsPublisher>();
auto mobile1 = std::make_shared<MobileClient>("张三");
auto mobile2 = std::make_shared<MobileClient>("李四");
auto email1 = std::make_shared<EmailClient>("zhangsan@example.com");
publisher->subscribe(mobile1);
publisher->subscribe(mobile2);
publisher->subscribe(email1);
publisher->publishNews("今日头条:AI技术突破");
publisher->publishNews("科技新闻:量子计算机问世");
return 0;
}
5.6 优缺点
| 优点 |
缺点 |
| 解耦主题和观察者 |
观察者过多影响性能 |
| 符合开闭原则 |
循环依赖可能导致死循环 |
| 广播通信 |
不知道观察者执行结果 |
| 动态增删观察者 |
|
6. 策略模式
6.1 模式定义
策略模式(Strategy Pattern):定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换。策略模式让算法独立于使用它的客户端而变化。
6.2 核心思想
- 将算法封装成独立的类
- 客户端通过接口调用算法
- 可以在运行时切换算法
6.3 应用场景
- 支付方式选择
- 排序算法选择
- 压缩算法选择
- 路径规划算法
- 折扣计算策略
6.4 代码实现
cpp
复制代码
#include <iostream>
#include <memory>
#include <vector>
#include <algorithm>
// 策略接口
class SortStrategy {
public:
virtual ~SortStrategy() {}
virtual void sort(std::vector<int>& data) = 0;
virtual std::string getName() const = 0;
};
// 冒泡排序策略
class BubbleSortStrategy : public SortStrategy {
public:
void sort(std::vector<int>& data) override {
int n = data.size();
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (data[j] > data[j + 1]) {
std::swap(data[j], data[j + 1]);
}
}
}
}
std::string getName() const override {
return "Bubble Sort";
}
};
// 快速排序策略
class QuickSortStrategy : public SortStrategy {
private:
int partition(std::vector<int>& data, int low, int high) {
int pivot = data[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (data[j] < pivot) {
std::swap(data[++i], data[j]);
}
}
std::swap(data[i + 1], data[high]);
return i + 1;
}
void quickSort(std::vector<int>& data, int low, int high) {
if (low < high) {
int pi = partition(data, low, high);
quickSort(data, low, pi - 1);
quickSort(data, pi + 1, high);
}
}
public:
void sort(std::vector<int>& data) override {
quickSort(data, 0, data.size() - 1);
}
std::string getName() const override {
return "Quick Sort";
}
};
// 标准库排序策略
class StdSortStrategy : public SortStrategy {
public:
void sort(std::vector<int>& data) override {
std::sort(data.begin(), data.end());
}
std::string getName() const override {
return "STD Sort";
}
};
// 上下文
class Sorter {
private:
std::unique_ptr<SortStrategy> strategy;
public:
void setStrategy(std::unique_ptr<SortStrategy> s) {
strategy = std::move(s);
}
void doSort(std::vector<int>& data) {
if (strategy) {
std::cout << "Using: " << strategy->getName() << std::endl;
strategy->sort(data);
}
}
};
// 使用
int main() {
std::vector<int> data1 = {64, 34, 25, 12, 22, 11, 90};
std::vector<int> data2 = {64, 34, 25, 12, 22, 11, 90};
std::vector<int> data3 = {64, 34, 25, 12, 22, 11, 90};
Sorter sorter;
// 使用冒泡排序
sorter.setStrategy(std::make_unique<BubbleSortStrategy>());
sorter.doSort(data1);
// 使用快速排序
sorter.setStrategy(std::make_unique<QuickSortStrategy>());
sorter.doSort(data2);
// 使用标准库排序
sorter.setStrategy(std::make_unique<StdSortStrategy>());
sorter.doSort(data3);
return 0;
}
6.5 实际应用案例:支付系统
cpp
复制代码
#include <iostream>
#include <memory>
#include <string>
// 支付策略接口
class PaymentStrategy {
public:
virtual ~PaymentStrategy() {}
virtual void pay(double amount) = 0;
virtual std::string getName() const = 0;
};
// 支付宝支付
class AlipayStrategy : public PaymentStrategy {
public:
void pay(double amount) override {
std::cout << "支付宝支付: ¥" << amount << std::endl;
}
std::string getName() const override {
return "支付宝";
}
};
// 微信支付
class WechatPayStrategy : public PaymentStrategy {
public:
void pay(double amount) override {
std::cout << "微信支付: ¥" << amount << std::endl;
}
std::string getName() const override {
return "微信";
}
};
// 银行卡支付
class CreditCardStrategy : public PaymentStrategy {
private:
std::string cardNumber;
public:
CreditCardStrategy(const std::string& card) : cardNumber(card) {}
void pay(double amount) override {
std::cout << "银行卡支付(" << cardNumber << "): ¥" << amount << std::endl;
}
std::string getName() const override {
return "银行卡";
}
};
// 购物车
class ShoppingCart {
private:
std::unique_ptr<PaymentStrategy> paymentStrategy;
double totalAmount = 0;
public:
void addItem(double price) {
totalAmount += price;
}
void setPaymentStrategy(std::unique_ptr<PaymentStrategy> strategy) {
paymentStrategy = std::move(strategy);
}
void checkout() {
if (paymentStrategy) {
std::cout << "使用 " << paymentStrategy->getName() << " 结算" << std::endl;
paymentStrategy->pay(totalAmount);
totalAmount = 0;
} else {
std::cout << "请选择支付方式" << std::endl;
}
}
};
// 使用
int main() {
ShoppingCart cart;
cart.addItem(100.0);
cart.addItem(50.0);
cart.addItem(30.0);
// 选择支付宝支付
cart.setPaymentStrategy(std::make_unique<AlipayStrategy>());
cart.checkout();
// 再次购物
cart.addItem(200.0);
// 选择微信支付
cart.setPaymentStrategy(std::make_unique<WechatPayStrategy>());
cart.checkout();
return 0;
}
6.6 优缺点
| 优点 |
缺点 |
| 算法可自由切换 |
客户端必须知道所有策略 |
| 避免多重条件判断 |
策略过多会增加类数量 |
| 符合开闭原则 |
|
| 易于扩展新策略 |
|
7. 状态机模式
7.1 模式定义
状态模式(State Pattern):允许一个对象在其内部状态改变时改变它的行为,对象看起来好像修改了它的类。
7.2 核心思想
- 将状态封装成独立的类
- 将状态转换逻辑委托给状态对象
- 消除大量的条件判断语句
7.3 应用场景
- 订单状态流转
- TCP连接状态
- 游戏角色状态
- 文档审批流程
- 自动售货机
7.4 代码实现
cpp
复制代码
#include <iostream>
#include <memory>
#include <string>
// 前向声明
class Order;
// 状态接口
class OrderState {
public:
virtual ~OrderState() {}
virtual void pay(Order* order) = 0;
virtual void ship(Order* order) = 0;
virtual void deliver(Order* order) = 0;
virtual void cancel(Order* order) = 0;
virtual std::string getName() const = 0;
};
// 订单类
class Order {
private:
std::shared_ptr<OrderState> state;
std::string orderId;
public:
Order(const std::string& id);
void setState(std::shared_ptr<OrderState> s) {
state = s;
}
void pay() {
std::cout << "尝试支付..." << std::endl;
state->pay(this);
}
void ship() {
std::cout << "尝试发货..." << std::endl;
state->ship(this);
}
void deliver() {
std::cout << "尝试确认收货..." << std::endl;
state->deliver(this);
}
void cancel() {
std::cout << "尝试取消订单..." << std::endl;
state->cancel(this);
}
std::string getStateName() const {
return state->getName();
}
std::string getOrderId() const {
return orderId;
}
};
// 具体状态:待支付
class PendingState : public OrderState {
public:
void pay(Order* order) override;
void ship(Order* order) override {
std::cout << "错误:订单未支付,无法发货" << std::endl;
}
void deliver(Order* order) override {
std::cout << "错误:订单未支付,无法确认收货" << std::endl;
}
void cancel(Order* order) override;
std::string getName() const override { return "待支付"; }
};
// 具体状态:已支付
class PaidState : public OrderState {
public:
void pay(Order* order) override {
std::cout << "错误:订单已支付" << std::endl;
}
void ship(Order* order) override;
void deliver(Order* order) override {
std::cout << "错误:订单未发货,无法确认收货" << std::endl;
}
void cancel(Order* order) override;
std::string getName() const override { return "已支付"; }
};
// 具体状态:已发货
class ShippedState : public OrderState {
public:
void pay(Order* order) override {
std::cout << "错误:订单已支付" << std::endl;
}
void ship(Order* order) override {
std::cout << "错误:订单已发货" << std::endl;
}
void deliver(Order* order) override;
void cancel(Order* order) override {
std::cout << "错误:订单已发货,无法取消" << std::endl;
}
std::string getName() const override { return "已发货"; }
};
// 具体状态:已完成
class CompletedState : public OrderState {
public:
void pay(Order* order) override {
std::cout << "错误:订单已完成" << std::endl;
}
void ship(Order* order) override {
std::cout << "错误:订单已完成" << std::endl;
}
void deliver(Order* order) override {
std::cout << "错误:订单已完成" << std::endl;
}
void cancel(Order* order) override {
std::cout << "错误:订单已完成,无法取消" << std::endl;
}
std::string getName() const override { return "已完成"; }
};
// 具体状态:已取消
class CancelledState : public OrderState {
public:
void pay(Order* order) override {
std::cout << "错误:订单已取消" << std::endl;
}
void ship(Order* order) override {
std::cout << "错误:订单已取消" << std::endl;
}
void deliver(Order* order) override {
std::cout << "错误:订单已取消" << std::endl;
}
void cancel(Order* order) override {
std::cout << "错误:订单已取消" << std::endl;
}
std::string getName() const override { return "已取消"; }
};
// 实现状态转换方法
void PendingState::pay(Order* order) {
std::cout << "支付成功!" << std::endl;
order->setState(std::make_shared<PaidState>());
}
void PendingState::cancel(Order* order) {
std::cout << "订单已取消" << std::endl;
order->setState(std::make_shared<CancelledState>());
}
void PaidState::ship(Order* order) {
std::cout << "发货成功!" << std::endl;
order->setState(std::make_shared<ShippedState>());
}
void PaidState::cancel(Order* order) {
std::cout << "订单已取消,将退款" << std::endl;
order->setState(std::make_shared<CancelledState>());
}
void ShippedState::deliver(Order* order) {
std::cout << "确认收货成功!" << std::endl;
order->setState(std::make_shared<CompletedState>());
}
// Order构造函数
Order::Order(const std::string& id)
: orderId(id), state(std::make_shared<PendingState>()) {}
// 使用
int main() {
Order order("ORDER-001");
std::cout << "订单状态: " << order.getStateName() << std::endl;
order.pay();
std::cout << "订单状态: " << order.getStateName() << std::endl;
order.ship();
std::cout << "订单状态: " << order.getStateName() << std::endl;
order.deliver();
std::cout << "订单状态: " << order.getStateName() << std::endl;
return 0;
}
7.5 优缺点
| 优点 |
缺点 |
| 消除大量条件判断 |
状态类数量增加 |
| 状态转换逻辑清晰 |
状态多时复杂度高 |
| 符合开闭原则 |
|
| 易于添加新状态 |
|
8. 责任链模式
8.1 模式定义
责任链模式(Chain of Responsibility Pattern):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
8.2 核心思想
- 每个处理者持有下一个处理者的引用
- 请求沿着链传递
- 每个处理者可以处理请求或传递给下一个
8.3 应用场景
- 审批流程
- 日志级别处理
- 异常处理
- 权限验证
- 过滤器链
8.4 代码实现
cpp
复制代码
#include <iostream>
#include <memory>
#include <string>
// 请求类
class Request {
public:
std::string type;
std::string content;
int amount;
Request(const std::string& t, const std::string& c, int a)
: type(t), content(c), amount(a) {}
};
// 处理者接口
class Handler {
protected:
std::shared_ptr<Handler> nextHandler;
public:
virtual ~Handler() {}
void setNext(std::shared_ptr<Handler> handler) {
nextHandler = handler;
}
virtual void handleRequest(const Request& request) {
if (nextHandler) {
nextHandler->handleRequest(request);
} else {
std::cout << "无法处理该请求" << std::endl;
}
}
virtual std::string getName() const = 0;
};
// 具体处理者:组长
class TeamLeader : public Handler {
public:
void handleRequest(const Request& request) override {
if (request.type == "请假" && request.amount <= 3) {
std::cout << "组长批准: " << request.content
<< " (" << request.amount << "天)" << std::endl;
} else {
std::cout << "组长无权处理,转交上级..." << std::endl;
Handler::handleRequest(request);
}
}
std::string getName() const override { return "组长"; }
};
// 具体处理者:经理
class Manager : public Handler {
public:
void handleRequest(const Request& request) override {
if (request.type == "请假" && request.amount <= 7) {
std::cout << "经理批准: " << request.content
<< " (" << request.amount << "天)" << std::endl;
} else if (request.type == "加薪" && request.amount <= 1000) {
std::cout << "经理批准加薪: " << request.amount << "元" << std::endl;
} else {
std::cout << "经理无权处理,转交上级..." << std::endl;
Handler::handleRequest(request);
}
}
std::string getName() const override { return "经理"; }
};
// 具体处理者:总经理
class GeneralManager : public Handler {
public:
void handleRequest(const Request& request) override {
if (request.type == "请假") {
std::cout << "总经理批准: " << request.content
<< " (" << request.amount << "天)" << std::endl;
} else if (request.type == "加薪") {
std::cout << "总经理批准加薪: " << request.amount << "元" << std::endl;
} else {
Handler::handleRequest(request);
}
}
std::string getName() const override { return "总经理"; }
};
// 使用
int main() {
// 创建处理者
auto teamLeader = std::make_shared<TeamLeader>();
auto manager = std::make_shared<Manager>();
auto generalManager = std::make_shared<GeneralManager>();
// 构建责任链
teamLeader->setNext(manager);
manager->setNext(generalManager);
// 测试请求
Request req1("请假", "病假", 2);
Request req2("请假", "年假", 5);
Request req3("请假", "长假", 15);
Request req4("加薪", "申请加薪", 500);
Request req5("加薪", "申请加薪", 2000);
std::cout << "=== 请假2天 ===" << std::endl;
teamLeader->handleRequest(req1);
std::cout << "\n=== 请假5天 ===" << std::endl;
teamLeader->handleRequest(req2);
std::cout << "\n=== 请假15天 ===" << std::endl;
teamLeader->handleRequest(req3);
std::cout << "\n=== 加薪500 ===" << std::endl;
teamLeader->handleRequest(req4);
std::cout << "\n=== 加薪2000 ===" << std::endl;
teamLeader->handleRequest(req5);
return 0;
}
8.5 实际应用案例:日志处理
cpp
复制代码
#include <iostream>
#include <memory>
#include <string>
#include <ctime>
// 日志级别
enum class LogLevel {
DEBUG,
INFO,
WARNING,
ERROR
};
// 日志记录
class LogRecord {
public:
LogLevel level;
std::string message;
LogRecord(LogLevel l, const std::string& msg) : level(l), message(msg) {}
};
// 日志处理器
class LogHandler {
protected:
std::shared_ptr<LogHandler> next;
LogLevel level;
public:
LogHandler(LogLevel l) : level(l) {}
void setNext(std::shared_ptr<LogHandler> handler) {
next = handler;
}
virtual void handle(const LogRecord& record) {
if (next) {
next->handle(record);
}
}
virtual std::string getLevelName() const = 0;
};
// 控制台日志处理器
class ConsoleLogHandler : public LogHandler {
public:
ConsoleLogHandler(LogLevel l) : LogHandler(l) {}
void handle(const LogRecord& record) override {
if (record.level >= level) {
std::cout << "[" << getLevelName() << "] " << record.message << std::endl;
}
LogHandler::handle(record);
}
std::string getLevelName() const override {
return "CONSOLE";
}
};
// 文件日志处理器
class FileLogHandler : public LogHandler {
public:
FileLogHandler(LogLevel l) : LogHandler(l) {}
void handle(const LogRecord& record) override {
if (record.level >= level) {
// 简化:实际应写入文件
std::cout << "[FILE] " << record.message << std::endl;
}
LogHandler::handle(record);
}
std::string getLevelName() const override {
return "FILE";
}
};
// 使用
int main() {
auto consoleHandler = std::make_shared<ConsoleLogHandler>(LogLevel::DEBUG);
auto fileHandler = std::make_shared<FileLogHandler>(LogLevel::WARNING);
consoleHandler->setNext(fileHandler);
consoleHandler->handle(LogRecord(LogLevel::DEBUG, "调试信息"));
consoleHandler->handle(LogRecord(LogLevel::INFO, "普通信息"));
consoleHandler->handle(LogRecord(LogLevel::WARNING, "警告信息"));
consoleHandler->handle(LogRecord(LogLevel::ERROR, "错误信息"));
return 0;
}
8.6 优缺点
| 优点 |
缺点 |
| 解耦发送者和处理者 |
请求可能无人处理 |
| 动态调整链 |
调试困难 |
| 符合单一职责原则 |
可能影响性能 |
| 易于扩展新处理者 |
|
9. 模板模式
9.1 模式定义
模板模式(Template Method Pattern):定义一个操作中算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
9.2 核心思想
- 父类定义算法骨架
- 子类实现具体步骤
- 控制子类扩展点
9.3 应用场景
- 数据处理流程
- 游戏框架
- 文档生成
- 测试框架
- 构建系统
9.4 代码实现
cpp
复制代码
#include <iostream>
#include <string>
#include <vector>
// 抽象类:数据解析器
class DataParser {
public:
// 模板方法:定义算法骨架
void parse(const std::string& filePath) {
openFile(filePath);
readData();
processData();
closeFile();
if (needReport()) {
generateReport();
}
}
virtual ~DataParser() {}
protected:
// 基本方法:子类必须实现
virtual void readData() = 0;
virtual void processData() = 0;
// 基本方法:子类可选实现
virtual void openFile(const std::string& path) {
std::cout << "打开文件: " << path << std::endl;
}
virtual void closeFile() {
std::cout << "关闭文件" << std::endl;
}
virtual void generateReport() {
std::cout << "生成报告" << std::endl;
}
// 钩子方法:控制流程
virtual bool needReport() const {
return false;
}
};
// 具体类:CSV解析器
class CSVParser : public DataParser {
protected:
void readData() override {
std::cout << "读取CSV数据" << std::endl;
}
void processData() override {
std::cout << "处理CSV数据" << std::endl;
}
bool needReport() const override {
return true;
}
};
// 具体类:JSON解析器
class JSONParser : public DataParser {
protected:
void readData() override {
std::cout << "读取JSON数据" << std::endl;
}
void processData() override {
std::cout << "处理JSON数据" << std::endl;
}
};
// 具体类:XML解析器
class XMLParser : public DataParser {
protected:
void openFile(const std::string& path) override {
std::cout << "打开XML文件: " << path << " (带验证)" << std::endl;
}
void readData() override {
std::cout << "读取XML数据" << std::endl;
}
void processData() override {
std::cout << "处理XML数据" << std::endl;
}
void generateReport() override {
std::cout << "生成XML验证报告" << std::endl;
}
bool needReport() const override {
return true;
}
};
// 使用
int main() {
std::cout << "=== CSV解析 ===" << std::endl;
CSVParser csvParser;
csvParser.parse("data.csv");
std::cout << "\n=== JSON解析 ===" << std::endl;
JSONParser jsonParser;
jsonParser.parse("data.json");
std::cout << "\n=== XML解析 ===" << std::endl;
XMLParser xmlParser;
xmlParser.parse("data.xml");
return 0;
}
9.5 实际应用案例:游戏框架
cpp
复制代码
#include <iostream>
#include <string>
// 游戏抽象类
class Game {
public:
// 模板方法:游戏主循环
void play() {
initialize();
startPlay();
while (!isGameOver()) {
update();
render();
}
endPlay();
}
virtual ~Game() {}
protected:
// 抽象方法:子类必须实现
virtual void initialize() = 0;
virtual void startPlay() = 0;
virtual void update() = 0;
virtual void render() = 0;
virtual void endPlay() = 0;
// 钩子方法
virtual bool isGameOver() const {
return false;
}
};
// 足球游戏
class FootballGame : public Game {
private:
int score = 0;
int maxScore = 5;
protected:
void initialize() override {
std::cout << "初始化足球游戏..." << std::endl;
}
void startPlay() override {
std::cout << "足球比赛开始!" << std::endl;
}
void update() override {
std::cout << "足球游戏更新中..." << std::endl;
score++;
}
void render() override {
std::cout << "渲染足球场景,当前比分: " << score << std::endl;
}
void endPlay() override {
std::cout << "足球比赛结束!" << std::endl;
}
bool isGameOver() const override {
return score >= maxScore;
}
};
// 篮球游戏
class BasketballGame : public Game {
private:
int score = 0;
int maxScore = 10;
protected:
void initialize() override {
std::cout << "初始化篮球游戏..." << std::endl;
}
void startPlay() override {
std::cout << "篮球比赛开始!" << std::endl;
}
void update() override {
std::cout << "篮球游戏更新中..." << std::endl;
score += 2;
}
void render() override {
std::cout << "渲染篮球场景,当前比分: " << score << std::endl;
}
void endPlay() override {
std::cout << "篮球比赛结束!" << std::endl;
}
bool isGameOver() const override {
return score >= maxScore;
}
};
// 使用
int main() {
std::cout << "=== 足球游戏 ===" << std::endl;
FootballGame football;
football.play();
std::cout << "\n=== 篮球游戏 ===" << std::endl;
BasketballGame basketball;
basketball.play();
return 0;
}
9.6 优缺点
| 优点 |
缺点 |
| 复用代码骨架 |
每个实现都需要子类 |
| 符合开闭原则 |
增加系统复杂度 |
| 控制子类扩展 |
难以理解父类流程 |
| 符合好莱坞原则 |
|
四、设计模式对比总结
4.1 模式分类
| 分类 |
模式 |
核心作用 |
| 创建型 |
单例模式 |
保证唯一实例 |
|
工厂模式 |
封装对象创建 |
| 结构型 |
适配器模式 |
接口转换 |
|
装饰器模式 |
动态添加功能 |
| 行为型 |
观察者模式 |
一对多依赖通知 |
|
策略模式 |
算法可互换 |
|
状态模式 |
状态改变行为 |
|
责任链模式 |
请求链式处理 |
|
模板模式 |
定义算法骨架 |
4.2 选择指南
| 需求场景 |
推荐模式 |
| 需要全局唯一实例 |
单例模式 |
| 创建对象逻辑复杂 |
工厂模式 |
| 接口不兼容需要转换 |
适配器模式 |
| 动态添加功能 |
装饰器模式 |
| 事件通知机制 |
观察者模式 |
| 算法需要切换 |
策略模式 |
| 状态流转控制 |
状态模式 |
| 多级审批/处理 |
责任链模式 |
| 流程固定,细节不同 |
模板模式 |
4.3 设计原则对应
| 设计原则 |
相关模式 |
| 单一职责原则 |
策略模式、观察者模式 |
| 开闭原则 |
工厂模式、装饰器模式、策略模式 |
| 里氏替换原则 |
所有使用继承的模式 |
| 接口隔离原则 |
适配器模式、策略模式 |
| 依赖倒置原则 |
工厂模式、策略模式 |
| 迪米特法则 |
外观模式、中介者模式 |
五、学习建议
5.1 学习顺序
复制代码
创建型 → 结构型 → 行为型
单例 → 工厂 → 适配器 → 装饰器 → 观察者 → 策略 → 状态 → 责任链 → 模板
5.2 学习方法
- 理解场景:先理解模式的应用场景
- 画UML图:画出类图理解结构
- 写代码:动手实现每个模式
- 看源码:在开源项目中找应用
- 做项目:在实际项目中应用
5.3 常见误区
| 误区 |
正确理解 |
| 模式越多越好 |
适度使用,避免过度设计 |
| 必须完全照搬 |
根据实际需求灵活变通 |
| 只学语法 |
更重要的是理解思想 |
| 单独使用 |
实际中常组合使用多种模式 |
文档版本:v1.0
创建时间:2026-04-07
适用范围:120天计划设计模式专项学习