还有哪些设计模式适合现代C++

好的,现代C++(C++11/14/17及以后)中,除了经典的设计模式,还有一些模式因其与现代语言特性的契合而更受推崇。以下是一些特别适合现代C++的设计模式及其优势:

1. 单例模式 (Singleton Pattern)

  • 现代实现: 利用 static 局部变量(C++11保证线程安全初始化)或 std::call_once

  • 优势: 简洁、线程安全。

  • 示例:

    cpp 复制代码
    class Singleton {
    public:
        static Singleton& getInstance() {
            static Singleton instance; // Thread-safe since C++11
            return instance;
        }
        // ... other members
    private:
        Singleton() = default; // Private constructor
        ~Singleton() = default;
        Singleton(const Singleton&) = delete;
        Singleton& operator=(const Singleton&) = delete;
    };

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

  • 现代实现: 结合返回 std::unique_ptrstd::shared_ptr,避免原始指针和手动内存管理。可使用 std::function 或 lambda 作为工厂函数。

  • 优势: 安全的内存管理,灵活的工厂定义。

  • 示例:

    cpp 复制代码
    class Product {
    public:
        virtual ~Product() = default;
        virtual void use() = 0;
    };
    class ConcreteProductA : public Product { ... };
    class ConcreteProductB : public Product { ... };
    using ProductPtr = std::unique_ptr<Product>;
    ProductPtr createProduct(const std::string& type) {
        if (type == "A") return std::make_unique<ConcreteProductA>();
        if (type == "B") return std::make_unique<ConcreteProductB>();
        return nullptr;
    }

3. 策略模式 (Strategy Pattern)

  • 现代实现: 使用 std::function、lambda 表达式或函数对象代替传统的接口/基类(如果策略逻辑简单)。

  • 优势: 减少类层次结构,代码更简洁,易于组合策略。

  • 示例:

    cpp 复制代码
    class Context {
        std::function<void()> strategy_;
    public:
        void setStrategy(std::function<void()> strategy) { strategy_ = std::move(strategy); }
        void executeStrategy() { if (strategy_) strategy_(); }
    };
    // Usage:
    Context ctx;
    ctx.setStrategy([]() { std::cout << "Strategy A\n"; });
    ctx.executeStrategy();

4. 观察者模式 (Observer Pattern)

  • 现代实现: 使用 std::function + std::vector(信号槽机制),或库如 boost::signals2。利用智能指针管理观察者生命周期。

  • 优势: 解耦更彻底,支持任意可调用对象作为观察者,避免继承。

  • 示例 (简化):

    cpp 复制代码
    class Subject {
        std::vector<std::function<void(int)>> observers_;
    public:
        void attach(std::function<void(int)> observer) { observers_.push_back(observer); }
        void notify(int data) {
            for (auto& obs : observers_) {
                obs(data);
            }
        }
    };

5. 构建者模式 (Builder Pattern)

  • 现代实现: 流畅接口,利用返回值链式调用。可结合 std::optional 或结构化绑定处理可选参数。

  • 优势: 构造复杂对象时代码可读性好,支持逐步构建和参数验证。

  • 示例:

    cpp 复制代码
    class Pizza {
        // ... (members like size, toppings, etc.)
        class Builder {
            Pizza pizza_;
        public:
            Builder& setSize(std::string size) { pizza_.size_ = size; return *this; }
            Builder& addTopping(std::string topping) { pizza_.toppings_.push_back(topping); return *this; }
            Pizza build() { return std::move(pizza_); } // Or return a unique_ptr
        };
    };
    // Usage:
    Pizza pizza = Pizza::Builder().setSize("Large").addTopping("Cheese").addTopping("Pepperoni").build();

6. 依赖注入 (Dependency Injection)

  • 现代实现: 构造函数注入或Setter注入,结合智能指针(std::unique_ptr, std::shared_ptr)传递依赖对象。框架如Boost.DI可简化。

  • 优势: 提高可测试性、可维护性和松耦合。是现代软件设计的重要原则。

  • 示例:

    cpp 复制代码
    class Service {
    public:
        virtual void doWork() = 0;
        virtual ~Service() = default;
    };
    class Client {
        std::unique_ptr<Service> service_;
    public:
        Client(std::unique_ptr<Service> service) : service_(std::move(service)) {}
        void execute() { service_->doWork(); }
    };

7. 适配器模式 (Adapter Pattern)

  • 现代实现: 适配新接口到遗留代码或第三方库。常结合 std::function 或 lambda 包装调用。

  • 优势: 集成新旧代码,无需修改原有接口。

  • 示例:

    cpp 复制代码
    // Legacy interface
    class LegacyPrinter {
    public:
        void printDocument(const char* doc) { ... }
    };
    // Modern interface
    class ModernPrinter {
    public:
        virtual void print(const std::string& doc) = 0;
    };
    // Adapter
    class LegacyPrinterAdapter : public ModernPrinter {
        LegacyPrinter legacyPrinter_;
    public:
        void print(const std::string& doc) override {
            legacyPrinter_.printDocument(doc.c_str());
        }
    };

8. 状态模式 (State Pattern)

  • 现代实现: 状态对象可使用智能指针管理。结合 std::variant (C++17) 可实现类型安全的状态机(有时称为状态模式的替代)。

  • 优势: 封装状态行为,简化状态转换逻辑。

  • 示例 (传统状态模式):

    cpp 复制代码
    class Context;
    class State {
    public:
        virtual void handle(Context* context) = 0;
        virtual ~State() = default;
    };
    class Context {
        std::unique_ptr<State> state_;
    public:
        void setState(std::unique_ptr<State> state) { state_ = std::move(state); }
        void request() { if (state_) state_->handle(this); }
    };

9. 装饰器模式 (Decorator Pattern)

  • 现代实现: 利用继承和组合。可结合 std::unique_ptr 管理被装饰对象。

  • 优势: 动态扩展对象功能,避免子类爆炸。

  • 示例:

    cpp 复制代码
    class Component {
    public:
        virtual void operation() = 0;
        virtual ~Component() = default;
    };
    class ConcreteComponent : public Component { ... };
    class Decorator : public Component {
    protected:
        std::unique_ptr<Component> component_;
    public:
        Decorator(std::unique_ptr<Component> comp) : component_(std::move(comp)) {}
        void operation() override { component_->operation(); }
    };
    class ConcreteDecoratorA : public Decorator {
    public:
        using Decorator::Decorator;
        void operation() override {
            Decorator::operation();
            // Add extra behavior
        }
    };

10. 访问者模式 (Visitor Pattern)

  • 现代实现: 虽然实现较复杂,但在需要遍历复杂结构(如AST)并执行多种操作时仍有用。可结合 std::variantstd::visit (C++17) 实现简化版(有时称为std::variant访问者)。

  • 优势: 将算法与对象结构分离,便于添加新操作。

  • 示例 (传统):

    cpp 复制代码
    class Element;
    class Visitor {
    public:
        virtual void visit(Element* element) = 0;
        virtual ~Visitor() = default;
    };
    class Element {
    public:
        virtual void accept(Visitor& visitor) = 0;
        virtual ~Element() = default;
    };
    class ConcreteElementA : public Element {
    public:
        void accept(Visitor& visitor) override { visitor.visit(this); }
    };
    // ... ConcreteVisitor implementations

选择建议

  • 优先组合而非继承: 现代C++鼓励使用组合、std::function、lambda 等,减少深度继承层次。
  • 善用智能指针: std::unique_ptrstd::shared_ptr 极大简化了资源管理和生命周期控制。
  • 利用新特性: std::optional, std::variant, std::any, std::function, lambda 等特性可以简化或改变某些模式的实现方式。
  • 考虑范围库 (Ranges) (C++20): 提供了一种声明式处理序列的新方式,有时可以替代迭代器模式的部分应用。
  • 避免过度设计: 设计模式是工具,应在确实需要解决特定问题时才使用,而不是为了用而用。

选择哪种模式取决于具体的应用场景和需要解决的问题。现代C++的特性让许多模式的实现更加简洁、安全和高效。

相关推荐
c++逐梦人1 小时前
C++ RAII流式日志库实现
开发语言·c++
Dshuishui1 小时前
学习一下 Python 包管理器 uv
开发语言·python·uv
Wave8451 小时前
C++ 面向对象基础:类、访问权限,构造函数,析构函数
开发语言·c++
t***5441 小时前
如何在现代C++项目中有效应用这些设计模式
开发语言·c++·设计模式
野生技术架构师1 小时前
2026年Java面试题集锦(含答案)
java·开发语言·面试
lolo大魔王1 小时前
Go语言的defer语句和Test功能测试函数
开发语言·后端·golang
kyle~1 小时前
导航---LIO(激光雷达-惯性里程计)算法
c++·算法·机器人·ros2·导航
杰众物联1 小时前
超高频FPC标签企业
c++
无限进步_2 小时前
【C++】私有虚函数与多态:访问权限不影响动态绑定
开发语言·c++·ide·windows·git·算法·visual studio