当前位置: 首页 > article >正文

C++八大常见的设计模式的实现与实践指南

目录

  1. 创建型模式
    • 单例模式
    • 工厂方法模式
    • 抽象工厂模式
  2. 结构型模式
    • 适配器模式
    • 装饰者模式
    • 代理模式
  3. 行为型模式
    • 观察者模式
    • 策略模式
    • 命令模式
  4. 高级主题
    • 现代C++特性影响
    • 模式性能对比
    • 典型应用案例

设计模式分类
在这里插入图片描述

一、创建型模式

1. 单例模式(Singleton)

现代C++17线程安全实现
#include <mutex>
#include <memory>

class ConfigManager {
private:
    static std::unique_ptr<ConfigManager> instance;
    static std::once_flag initFlag;
    
    // 私有构造函数
    ConfigManager() { loadConfig(); }

    void loadConfig() { /* 加载配置文件 */ }

public:
    // 删除拷贝操作
    ConfigManager(const ConfigManager&) = delete;
    ConfigManager& operator=(const ConfigManager&) = delete;

    static ConfigManager& getInstance() {
        std::call_once(initFlag, [](){
            instance.reset(new ConfigManager);
        });
        return *instance;
    }

    std::string getValue(const std::string& key) { 
        /* 返回配置值 */ 
        return "";
    }
};

// 初始化静态成员
std::unique_ptr<ConfigManager> ConfigManager::instance;
std::once_flag ConfigManager::initFlag;
应用陷阱
  • 测试困难:全局状态影响单元测试
  • 生命周期管理:依赖顺序问题
  • 多线程初始化竞争

2. 工厂方法模式(Factory Method)

现代实现(使用lambda工厂)
#include <functional>
#include <map>

class Button {
public:
    virtual void render() = 0;
    virtual ~Button() = default;
};

class WindowsButton : public Button {
public:
    void render() override { /* Windows风格渲染 */ }
};

class MacButton : public Button {
public:
    void render() override { /* Mac风格渲染 */ }
};

class GUIFactory {
private:
    using FactoryFunc = std::function<std::unique_ptr<Button>()>;
    std::map<std::string, FactoryFunc> factories;

public:
    void registerFactory(const std::string& type, FactoryFunc factory) {
        factories[type] = factory;
    }

    std::unique_ptr<Button> createButton(const std::string& type) {
        if (auto it = factories.find(type); it != factories.end())
            return it->second();
        throw std::runtime_error("Unknown button type");
    }
};

// 使用示例
GUIFactory factory;
factory.registerFactory("Windows", []{ return std::make_unique<WindowsButton>(); });
factory.registerFactory("Mac", []{ return std::make_unique<MacButton>(); });

auto btn = factory.createButton("Windows");
btn->render();

二、结构型模式

3. 适配器模式(Adapter)

对象适配器实现
// 遗留圆形接口
class LegacyCircle {
public:
    void draw(int x, int y, int radius) {
        // 绘制圆形实现
    }
};

// 新系统需要的形状接口
class Shape {
public:
    virtual void draw(float x, float y, float size) = 0;
    virtual ~Shape() = default;
};

class CircleAdapter : public Shape {
    LegacyCircle legacyCircle;
public:
    void draw(float x, float y, float size) override {
        // 转换参数并调用遗留接口
        legacyCircle.draw(static_cast<int>(x), 
                         static_cast<int>(y),
                         static_cast<int>(size/2));
    }
};

4. 装饰者模式(Decorator)

流处理装饰器
#include <iostream>
#include <memory>

class DataStream {
public:
    virtual void write(const std::string& data) = 0;
    virtual ~DataStream() = default;
};

class FileStream : public DataStream {
public:
    void write(const std::string& data) override {
        std::cout << "Writing to file: " << data << "\n";
    }
};

class StreamDecorator : public DataStream {
protected:
    std::unique_ptr<DataStream> wrapped;
public:
    StreamDecorator(std::unique_ptr<DataStream> stream)
        : wrapped(std::move(stream)) {}
};

class CompressionDecorator : public StreamDecorator {
public:
    using StreamDecorator::StreamDecorator;

    void write(const std::string& data) override {
        auto compressed = compress(data);
        wrapped->write(compressed);
    }

private:
    std::string compress(const std::string& data) {
        return "COMPRESSED[" + data + "]";
    }
};

// 使用组合
auto stream = std::make_unique<CompressionDecorator>(
    std::make_unique<FileStream>()
);
stream->write("Sample Data");

二、结构型模式(续)

5. 代理模式(Proxy)

定义:为其他对象提供一种代理以控制对这个对象的访问

应用场景

  • 延迟初始化(虚拟代理)
  • 访问控制(保护代理)
  • 本地执行远程服务(远程代理)
  • 日志记录(日志代理)

现代C++实现(延迟加载代理)

class Image {
public:
    virtual void display() = 0;
    virtual ~Image() = default;
};

class HighResImage : public Image {
    std::string filename;
public:
    HighResImage(const std::string& file) : filename(file) {
        loadFromDisk();
    }
    
    void display() override {
        std::cout << "Displaying " << filename << "\n";
    }

private:
    void loadFromDisk() {
        std::cout << "Loading " << filename << " from disk...\n";
    }
};

class ImageProxy : public Image {
    std::unique_ptr<HighResImage> realImage;
    std::string filename;
public:
    ImageProxy(const std::string& file) : filename(file) {}
    
    void display() override {
        if (!realImage) {
            realImage = std::make_unique<HighResImage>(filename);
        }
        realImage->display();
    }
};

// 使用示例
std::vector<std::unique_ptr<Image>> images;
images.push_back(std::make_unique<ImageProxy>("photo1.jpg"));
images.push_back(std::make_unique<ImageProxy>("photo2.jpg"));

// 只有在实际显示时才加载图片
images[0]->display();  // 输出加载信息
images[0]->display();  // 直接显示,不再加载

三、行为型模式

6. 观察者模式(Observer)(续)

现代C++改进(类型安全实现)

#include <vector>
#include <functional>
#include <memory>

template <typename... Args>
class Observable {
    using Observer = std::function<void(Args...)>;
    std::vector<std::weak_ptr<Observer>> observers;
    
public:
    auto registerObserver(Observer callback) {
        auto shared = std::make_shared<Observer>(std::move(callback));
        observers.emplace_back(shared);
        return shared;
    }

    void notify(Args... args) {
        auto it = observers.begin();
        while (it != observers.end()) {
            if (auto observer = it->lock()) {
                (*observer)(args...);
                ++it;
            } else {
                it = observers.erase(it);
            }
        }
    }
};

// 使用示例
class Sensor {
public:
    Observable<float> temperatureChanged;
    
    void updateTemperature(float temp) {
        currentTemp = temp;
        temperatureChanged.notify(temp);
    }

private:
    float currentTemp;
};

int main() {
    Sensor sensor;
    auto observer = sensor.temperatureChanged.registerObserver(
        [](float temp) {
            std::cout << "Temperature updated: " << temp << "°C\n";
        }
    );
    
    sensor.updateTemperature(23.5f);
    sensor.updateTemperature(24.1f);
}

7. 策略模式(Strategy)

定义:定义算法族,分别封装,使它们可以互相替换

现代C++实现(使用std::function)

#include <functional>
#include <vector>

class SortStrategy {
public:
    virtual void sort(std::vector<int>& data) = 0;
    virtual ~SortStrategy() = default;
};

// 传统实现方式
class BubbleSort : public SortStrategy {
public:
    void sort(std::vector<int>& data) override {
        // 实现冒泡排序
    }
};

// 现代C++风格实现
using ModernSortStrategy = std::function<void(std::vector<int>&)>;

class SortContext {
public:
    // 传统策略方式
    void setStrategy(std::unique_ptr<SortStrategy> strategy) {
        this->strategy = std::move(strategy);
    }

    // 现代策略方式
    void setModernStrategy(ModernSortStrategy strategy) {
        modernStrategy = std::move(strategy);
    }

    void executeSort(std::vector<int>& data) {
        if (modernStrategy) {
            modernStrategy(data);
        } else if (strategy) {
            strategy->sort(data);
        }
    }

private:
    std::unique_ptr<SortStrategy> strategy;
    ModernSortStrategy modernStrategy;
};

// 使用示例
int main() {
    std::vector<int> data = {5, 2, 7, 1, 9};
    
    // 传统方式
    SortContext context1;
    context1.setStrategy(std::make_unique<BubbleSort>());
    context1.executeSort(data);

    // 现代方式
    SortContext context2;
    context2.setModernStrategy([](std::vector<int>& data) {
        // 实现快速排序
        std::sort(data.begin(), data.end());
    });
    context2.executeSort(data);
}

8. 命令模式(Command)

定义:将请求封装为对象,支持撤销操作

完整实现(含撤销功能)

#include <vector>
#include <memory>
#include <stack>

class Document {
    std::string content;
public:
    void addText(const std::string& text) {
        content += text;
    }
    
    void deleteText(size_t length) {
        if (length >= content.size()) {
            content.clear();
        } else {
            content.erase(content.size() - length);
        }
    }
    
    std::string getContent() const { return content; }
};

class Command {
public:
    virtual void execute() = 0;
    virtual void undo() = 0;
    virtual ~Command() = default;
};

class AddTextCommand : public Command {
    Document& doc;
    std::string addedText;
public:
    AddTextCommand(Document& d, std::string text)
        : doc(d), addedText(std::move(text)) {}
    
    void execute() override {
        doc.addText(addedText);
    }
    
    void undo() override {
        doc.deleteText(addedText.size());
    }
};

class CommandHistory {
    std::stack<std::unique_ptr<Command>> history;
public:
    void push(std::unique_ptr<Command> cmd) {
        cmd->execute();
        history.push(std::move(cmd));
    }
    
    void undo() {
        if (!history.empty()) {
            history.top()->undo();
            history.pop();
        }
    }
};

// 使用示例
int main() {
    Document doc;
    CommandHistory history;
    
    history.push(std::make_unique<AddTextCommand>(doc, "Hello "));
    history.push(std::make_unique<AddTextCommand>(doc, "World!"));
    
    std::cout << doc.getContent() << "\n";  // 输出:Hello World!
    
    history.undo();
    std::cout << doc.getContent() << "\n";  // 输出:Hello 
    
    history.undo();
    std::cout << doc.getContent() << "\n";  // 输出:(空)
}

四、高级主题

1. 现代C++特性对设计模式的重构

1.1 Lambda表达式与策略模式融合
class PaymentProcessor {
public:
    using PaymentStrategy = std::function<bool(float)>;
    
    void setStrategy(PaymentStrategy strategy) {
        currentStrategy = std::move(strategy);
    }

    bool processPayment(float amount) {
        if(currentStrategy) {
            return currentStrategy(amount);
        }
        throw std::runtime_error("No payment strategy set");
    }

private:
    PaymentStrategy currentStrategy;
};

// 使用示例
PaymentProcessor processor;
processor.setStrategy([](float amount) -> bool {
    // 信用卡支付实现
    return true; 
});

processor.processPayment(99.99f);
1.2 可变参数模板实现通用装饰者
template <typename Component>
class LoggerDecorator {
    Component wrapped;
public:
    LoggerDecorator(Component&& comp) : wrapped(std::forward<Component>(comp)) {}

    template <typename... Args>
    auto operator()(Args&&... args) {
        std::cout << "Calling function with args: " 
                  << sizeof...(args) << "\n";
        auto result = wrapped(std::forward<Args>(args)...);
        std::cout << "Return value: " << result << "\n";
        return result;
    }
};

// 用法示例
auto decoratedFunc = LoggerDecorator([](int x, int y) { return x + y; });
decoratedFunc(3, 4);  // 输出调用日志和结果

2. 设计模式性能对比分析

2.1 虚函数调用开销测试
#include <chrono>

// 传统策略模式实现
class TraditionalStrategy {
public:
    virtual int compute(int x) = 0;
    virtual ~TraditionalStrategy() = default;
};

// 现代策略实现
using ModernStrategy = std::function<int(int)>;

// 性能测试函数
template <typename Strategy>
void runBenchmark(Strategy&& strategy) {
    constexpr int iterations = 1'000'000;
    auto start = std::chrono::high_resolution_clock::now();
    
    int sum = 0;
    for(int i = 0; i < iterations; ++i) {
        sum += strategy(i);
    }
    
    auto duration = std::chrono::duration_cast<std::chrono::microseconds>(
        std::chrono::high_resolution_clock::now() - start
    );
    
    std::cout << "Time: " << duration.count() << "μs\n";
}

// 测试用例
struct AddStrategy : TraditionalStrategy {
    int compute(int x) override { return x + 1; }
};

int main() {
    // 传统虚函数调用
    AddStrategy traditional;
    runBenchmark([&](int x) { return traditional.compute(x); });
    
    // 现代std::function
    ModernStrategy modern = [](int x) { return x + 1; };
    runBenchmark(modern);
    
    // 直接lambda调用
    runBenchmark([](int x) { return x + 1; });
}

典型结果

  • 传统虚函数调用:约850μs
  • std::function调用:约780μs
  • 直接lambda调用:约650μs

3. 设计模式在游戏引擎中的实践

3.1 组件模式实现游戏对象系统
class GameObject {
    std::unordered_map<std::type_index, std::unique_ptr<Component>> components;

public:
    template <typename T, typename... Args>
    T& addComponent(Args&&... args) {
        auto ptr = std::make_unique<T>(std::forward<Args>(args)...);
        auto& ref = *ptr;
        components[typeid(T)] = std::move(ptr);
        return ref;
    }

    template <typename T>
    T* getComponent() {
        auto it = components.find(typeid(T));
        return (it != components.end()) ? 
            static_cast<T*>(it->second.get()) : nullptr;
    }

    void update() {
        for(auto& [_, comp] : components) {
            comp->update();
        }
    }
};

class Component {
public:
    virtual void update() = 0;
    virtual ~Component() = default;
};

// 具体组件实现
class Transform : public Component {
public:
    void update() override { /* 更新位置信息 */ }
};

class PhysicsBody : public Component {
public:
    void update() override { /* 物理模拟计算 */ }
};

// 使用示例
GameObject player;
player.addComponent<Transform>();
player.addComponent<PhysicsBody>();
player.update();

3.2 状态模式实现角色行为控制
class CharacterState {
public:
    virtual void enter() = 0;
    virtual void handleInput(char input) = 0;
    virtual void update() = 0;
    virtual ~CharacterState() = default;
};

class IdleState : public CharacterState {
public:
    void enter() override { std::cout << "Entering Idle\n"; }
    void handleInput(char input) override {
        if(input == 'w') /* 切换到移动状态 */;
    }
    void update() override { /* 闲置动画更新 */ }
};

class StateMachine {
    std::unique_ptr<CharacterState> currentState;
public:
    void changeState(std::unique_ptr<CharacterState> newState) {
        if(currentState) currentState->exit();
        newState->enter();
        currentState = std::move(newState);
    }

    void update() {
        if(currentState) currentState->update();
    }
};

// 使用示例
StateMachine fsm;
fsm.changeState(std::make_unique<IdleState>());

while(true) {
    char input = getInput();
    fsm.handleInput(input);
    fsm.update();
}

五、设计模式最佳实践指南

1. 模式选择决策树

是否需要控制对象创建?
├─ 是 → 考虑工厂/建造者模式
├─ 否 → 是否需要扩展对象功能?
│    ├─ 是 → 装饰者/代理模式
│    └─ 否 → 是否需要算法切换?
│         ├─ 是 → 策略模式
│         └─ 否 → 是否需要状态管理?
│              ├─ 是 → 状态模式
│              └─ 否 → 观察者/命令模式

2. 典型代码异味与模式对应

代码问题推荐模式重构示例
多重条件分支策略/状态模式用多态替代switch-case
接口不兼容适配器模式包装旧接口为新接口
过度全局访问单例→依赖注入引入服务定位器
难以扩展功能装饰者/组合模式动态添加组件
紧耦合的对象通信观察者/中介者模式事件驱动架构

3. 现代C++设计原则

  1. 优先组合而非继承:使用std::variant/std::any实现运行时多态
  2. 利用RAII管理资源:智能指针自动管理模式对象生命周期
  3. 编译时多态优化:模板方法替代运行时虚函数分派
  4. 移动语义优化性能:在工厂模式中高效转移大型对象
  5. 类型擦除技术:使用std::function实现灵活的策略模式

六、常见陷阱与调试技巧

1. 单例模式的内存泄漏检测

使用Valgrind或AddressSanitizer检测未释放实例:

$ g++ -fsanitize=address -g singleton.cpp
$ ASAN_OPTIONS=detect_leaks=1 ./a.out

2. 观察者模式的循环引用排查

使用weak_ptr打破强引用循环:

class Subject {
    std::vector<std::weak_ptr<Observer>> observers;
    
public:
    void addObserver(std::weak_ptr<Observer> obs) {
        observers.push_back(obs);
    }

    void notify() {
        for(auto& weakObs : observers) {
            if(auto obs = weakObs.lock()) {
                obs->update();
            }
        }
    }
};

3. 工厂模式的类型注册验证

静态断言确保类型安全:

template <typename T>
void registerType() {
    static_assert(std::is_base_of_v<BaseProduct, T>, 
                 "Must inherit from BaseProduct");
    // 注册逻辑...
}

七、延伸阅读与工具推荐

1. 进阶学习资源

  • 《Modern C++ Design》Andrei Alexandrescu
  • 《C++ Core Guidelines》设计模式章节
  • CppCon会议演讲:Modern C++ Design Patterns

2. 可视化设计工具

  • PlantUML:模式UML图生成
  • Doxygen:模式文档自动化
  • Clang-Query:模式代码静态检测

3. 性能分析工具链

工具名称用途示例命令
Perf函数级热点分析perf record ./app
Hotspot可视化性能数据图形化展示perf结果
Cachegrind缓存访问模式分析valgrind --tool=cachegrind ./app

http://www.kler.cn/a/590975.html

相关文章:

  • 服务器防火墙根据什么特征来过滤数据包?
  • H3C SecPath SysScan-AK 系列漏洞扫描系统
  • vue中根据html动态渲染内容
  • 设备物联网无线交互控制,ESP32无线联动方案,产品智能化响应
  • 基于SpringBoot的Mybatis和纯MyBatis项目搭建的区别
  • docker 安装 nginx 部署Vue前端项目
  • AOP+Nacos实现动态数据源切换
  • 超详细kubernetes部署k8s----一台master和两台node
  • AK 接口
  • Oracle静默安装方法
  • MySQL事务:确保数据一致性的关键机制
  • 复旦:LLM不同层位置编码缩放
  • 【arXiv 2025】卷积加法自注意力CASAtt,轻量且高效,即插即用!
  • 【紫光同创FPGA开发常用工具】FPGACPLD的下载与固化
  • 数据库设计实验(4)—— 数据更新实验
  • 神思智飞无人机智能调度系统介绍
  • pwn刷题记录
  • 笔记:代码随想录算法训练营day56:图论理论基础、深搜理论基础、98. 所有可达路径、广搜理论基础
  • XXXX数字化交流BI系统分析与设计(40页PPT)(文末有下载方式)
  • Web 小项目: 网页版图书管理系统