Skip to content
Go back

设计模式C++17实现

Edit page

23种设计模式的现代C++17实现


目录

类型模式
创建型单例、工厂方法、抽象工厂、建造者、原型
结构型适配器、桥接、组合、装饰、外观、享元、代理
行为型责任链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者

一、创建型模式

1. 单例模式 (Singleton)

意图:确保类只有一个实例,提供全局访问点
场景:配置中心、日志系统、数据库连接池

#include <iostream>
#include <string>

class Singleton {
public:
    static Singleton& instance() {
        static Singleton s;  // C++11起线程安全
        return s;
    }
    
    void setData(const std::string& d) { data_ = d; }
    std::string getData() const { return data_; }
    
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

private:
    Singleton() = default;
    std::string data_;
};

int main() {
    Singleton::instance().setData("Hello");
    std::cout << Singleton::instance().getData() << std::endl;
    
    // 验证单例
    auto& s1 = Singleton::instance();
    auto& s2 = Singleton::instance();
    std::cout << "Same: " << (&s1 == &s2) << std::endl;
    
    return 0;
}

2. 工厂方法 (Factory Method)

意图:定义创建对象的接口,让子类决定实例化哪个类
场景:需要延迟实例化、创建逻辑复杂

#include <iostream>
#include <memory>
#include <string_view>
#include <optional>

class Product {
public:
    virtual ~Product() = default;
    virtual void use() = 0;
};

class ProductA : public Product {
public:
    void use() override { std::cout << "Product A\n"; }
};

class ProductB : public Product {
public:
    void use() override { std::cout << "Product B\n"; }
};

// C++17: 使用string_view和optional的工厂
class Factory {
public:
    static std::optional<std::unique_ptr<Product>> create(std::string_view type) {
        if (type == "A") return std::make_unique<ProductA>();
        if (type == "B") return std::make_unique<ProductB>();
        return std::nullopt;
    }
};

// 泛型工厂
template<typename T, typename... Args>
auto make(Args&&... args) {
    return std::make_unique<T>(std::forward<Args>(args)...);
}

int main() {
    if (auto p = Factory::create("A")) {
        (*p)->use();
    }
    
    auto product = make<ProductB>();
    product->use();
    
    return 0;
}

3. 抽象工厂 (Abstract Factory)

意图:创建相关对象家族,无需指定具体类
场景:跨平台UI、数据库访问层

#include <iostream>
#include <memory>
#include <string_view>

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

class TextBox {
public:
    virtual ~TextBox() = default;
    virtual void input(std::string_view text) = 0;
};

// Windows产品族
class WinButton : public Button {
public:
    void click() override { std::cout << "Win Button\n"; }
};

class WinTextBox : public TextBox {
public:
    void input(std::string_view text) override {
        std::cout << "Win TextBox: " << text << "\n";
    }
};

// Mac产品族
class MacButton : public Button {
public:
    void click() override { std::cout << "Mac Button\n"; }
};

class MacTextBox : public TextBox {
public:
    void input(std::string_view text) override {
        std::cout << "Mac TextBox: " << text << "\n";
    }
};

// C++17: 模板工厂
template<typename ButtonT, typename TextBoxT>
class Factory {
public:
    static_assert(std::is_base_of_v<Button, ButtonT>);
    static_assert(std::is_base_of_v<TextBox, TextBoxT>);
    
    auto createButton() { return std::make_unique<ButtonT>(); }
    auto createTextBox() { return std::make_unique<TextBoxT>(); }
};

using WinFactory = Factory<WinButton, WinTextBox>;
using MacFactory = Factory<MacButton, MacTextBox>;

int main() {
    WinFactory win;
    auto btn = win.createButton();
    btn->click();
    
    MacFactory mac;
    auto txt = mac.createTextBox();
    txt->input("Hello");
    
    return 0;
}

4. 建造者模式 (Builder)

意图:分步骤构建复杂对象
场景:对象构造参数多、需要不同配置

#include <iostream>
#include <string>
#include <optional>

struct Computer {
    std::string cpu;
    std::string ram;
    std::string ssd;
    
    void show() const {
        std::cout << cpu << ", " << ram << ", " << ssd << "\n";
    }
};

// C++17: 使用optional的严格建造者
class Builder {
public:
    Builder& cpu(std::string_view c) { cpu_ = std::string(c); return *this; }
    Builder& ram(std::string_view r) { ram_ = std::string(r); return *this; }
    Builder& ssd(std::string_view s) { ssd_ = std::string(s); return *this; }
    
    std::optional<Computer> build() {
        if (!cpu_ || !ram_) return std::nullopt;
        return Computer{*cpu_, *ram_, ssd_.value_or("256GB")};
    }

private:
    std::optional<std::string> cpu_;
    std::optional<std::string> ram_;
    std::optional<std::string> ssd_;
};

// 结构化绑定应用
auto createPC() {
    return std::make_tuple(std::string("i9"), std::string("64GB"), std::string("2TB"));
}

int main() {
    auto pc = Builder{}.cpu("i7").ram("32GB").ssd("1TB").build();
    if (pc) pc->show();
    
    // 结构化绑定
    auto [cpu, ram, ssd] = createPC();
    Computer pc2{cpu, ram, ssd};
    pc2.show();
    
    return 0;
}

5. 原型模式 (Prototype)

意图:通过复制现有对象创建新对象
场景:对象创建成本高、需要保存状态

#include <iostream>
#include <memory>
#include <string_view>
#include <unordered_map>

// CRTP自动克隆
template<typename Derived>
class Cloneable {
public:
    std::unique_ptr<Derived> clone() const {
        return std::make_unique<Derived>(static_cast<const Derived&>(*this));
    }
};

class Document : public Cloneable<Document> {
public:
    explicit Document(std::string_view title) : title_(title) {}
    void show() const { std::cout << title_ << "\n"; }
    void setTitle(std::string_view t) { title_ = t; }
private:
    std::string title_;
};

// C++17: inline变量的注册表
class Registry {
public:
    static Registry& instance() {
        static Registry r;
        return r;
    }
    
    void add(std::string_view name, std::unique_ptr<Document> doc) {
        prototypes_[std::string(name)] = std::move(doc);
    }
    
    std::unique_ptr<Document> create(std::string_view name) {
        auto it = prototypes_.find(std::string(name));
        return (it != prototypes_.end()) ? it->second->clone() : nullptr;
    }

private:
    Registry() = default;
    std::unordered_map<std::string, std::unique_ptr<Document>> prototypes_;
};

int main() {
    Document doc1("Report");
    auto doc2 = doc1.clone();
    
    doc1.show();
    doc2->show();
    
    // 使用注册表
    Registry::instance().add("template", std::make_unique<Document>("Template"));
    auto doc3 = Registry::instance().create("template");
    if (doc3) doc3->show();
    
    return 0;
}

二、结构型模式

6. 适配器模式 (Adapter)

意图:将一个接口转换成客户希望的另一个接口
场景:复用旧类、统一不同接口

#include <iostream>
#include <memory>
#include <string_view>

class Target {
public:
    virtual ~Target() = default;
    virtual void request(std::string_view data) = 0;
};

class Adaptee {
public:
    void specificRequest(std::string_view data) {
        std::cout << "Adaptee: " << data << "\n";
    }
};

// C++17: 使用string_view的适配器
class Adapter : public Target {
public:
    explicit Adapter(std::unique_ptr<Adaptee> a) : adaptee_(std::move(a)) {}
    
    void request(std::string_view data) override {
        adaptee_->specificRequest(data);
    }

private:
    std::unique_ptr<Adaptee> adaptee_;
};

int main() {
    auto adapter = std::make_unique<Adapter>(std::make_unique<Adaptee>());
    adapter->request("Hello");
    
    return 0;
}

7. 桥接模式 (Bridge)

意图:分离抽象与实现,使它们可独立变化
场景:多维度变化、避免类爆炸

#include <iostream>
#include <memory>

class Implementation {
public:
    virtual ~Implementation() = default;
    virtual void operationImpl() = 0;
};

class ConcreteImplA : public Implementation {
public:
    void operationImpl() override { std::cout << "Implementation A\n"; }
};

class ConcreteImplB : public Implementation {
public:
    void operationImpl() override { std::cout << "Implementation B\n"; }
};

class Abstraction {
public:
    explicit Abstraction(std::unique_ptr<Implementation> impl) 
        : impl_(std::move(impl)) {}
    
    virtual void operation() {
        impl_->operationImpl();
    }

protected:
    std::unique_ptr<Implementation> impl_;
};

class ExtendedAbstraction : public Abstraction {
public:
    using Abstraction::Abstraction;
    
    void operation() override {
        std::cout << "Extended: ";
        impl_->operationImpl();
    }
};

int main() {
    Abstraction a(std::make_unique<ConcreteImplA>());
    a.operation();
    
    ExtendedAbstraction b(std::make_unique<ConcreteImplB>());
    b.operation();
    
    return 0;
}

8. 组合模式 (Composite)

意图:将对象组合成树形结构表示”部分-整体”层次
场景:文件系统、UI组件树

#include <iostream>
#include <vector>
#include <variant>
#include <memory>
#include <string>

struct File {
    std::string name;
    size_t size;
};

class Directory;
using Node = std::variant<File, std::shared_ptr<Directory>>;

class Directory {
public:
    explicit Directory(std::string n) : name_(std::move(n)) {}
    
    void add(Node node) { children_.push_back(std::move(node)); }
    
    // C++17: 使用std::visit
    void display(int indent = 0) const {
        std::cout << std::string(indent, ' ') << name_ << "/\n";
        for (const auto& child : children_) {
            std::visit([indent](const auto& item) {
                using T = std::decay_t<decltype(item)>;
                if constexpr (std::is_same_v<T, File>) {
                    std::cout << std::string(indent + 2, ' ') 
                              << item.name << " (" << item.size << ")\n";
                } else {
                    item->display(indent + 2);
                }
            }, child);
        }
    }

private:
    std::string name_;
    std::vector<Node> children_;
};

int main() {
    auto root = std::make_shared<Directory>("root");
    root->add(File{"a.txt", 100});
    
    auto dir = std::make_shared<Directory>("subdir");
    dir->add(File{"b.txt", 200});
    root->add(dir);
    
    root->display();
    
    return 0;
}

9. 装饰器模式 (Decorator)

意图:动态地给对象添加额外职责
场景:扩展功能、避免子类爆炸

#include <iostream>
#include <memory>
#include <functional>

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

class ConcreteComponent : public Component {
public:
    void operation() override { std::cout << "Base"; }
};

class Decorator : public Component {
public:
    explicit Decorator(std::unique_ptr<Component> c) : component_(std::move(c)) {}
    
    void operation() override {
        component_->operation();
    }

protected:
    std::unique_ptr<Component> component_;
};

class ConcreteDecoratorA : public Decorator {
public:
    using Decorator::Decorator;
    void operation() override {
        std::cout << "[";
        Decorator::operation();
        std::cout << "]";
    }
};

class ConcreteDecoratorB : public Decorator {
public:
    using Decorator::Decorator;
    void operation() override {
        std::cout << "{";
        Decorator::operation();
        std::cout << "}";
    }
};

// C++17: 使用lambda的装饰器
class LambdaDecorator : public Component {
public:
    LambdaDecorator(std::unique_ptr<Component> c, 
                    std::function<void()> before,
                    std::function<void()> after)
        : component_(std::move(c)), before_(before), after_(after) {}
    
    void operation() override {
        before_();
        component_->operation();
        after_();
    }

private:
    std::unique_ptr<Component> component_;
    std::function<void()> before_;
    std::function<void()> after_;
};

int main() {
    auto c = std::make_unique<ConcreteComponent>();
    auto d1 = std::make_unique<ConcreteDecoratorA>(std::move(c));
    auto d2 = std::make_unique<ConcreteDecoratorB>(std::move(d1));
    d2->operation();
    std::cout << "\n";
    
    // Lambda装饰器
    auto base = std::make_unique<ConcreteComponent>();
    auto decorated = std::make_unique<LambdaDecorator>(
        std::move(base),
        []() { std::cout << "Before-"; },
        []() { std::cout << "-After"; }
    );
    decorated->operation();
    std::cout << "\n";
    
    return 0;
}

10. 外观模式 (Facade)

意图:为子系统提供统一的高层接口
场景:简化复杂系统、分层架构

#include <iostream>
#include <tuple>
#include <string_view>

class SubsystemA {
public:
    void operationA() { std::cout << "Subsystem A\n"; }
};

class SubsystemB {
public:
    void operationB() { std::cout << "Subsystem B\n"; }
};

class SubsystemC {
public:
    void operationC() { std::cout << "Subsystem C\n"; }
};

// C++17: 简化接口 + 结构化绑定
class Facade {
public:
    void simpleOperation() {
        std::cout << "=== Start ===\n";
        a_.operationA();
        b_.operationB();
        c_.operationC();
        std::cout << "=== End ===\n";
    }
    
    // 结构化绑定返回多值
    auto getStatus() {
        return std::make_tuple(true, 42, std::string("OK"));
    }

private:
    SubsystemA a_;
    SubsystemB b_;
    SubsystemC c_;
};

int main() {
    Facade f;
    f.simpleOperation();
    
    auto [ok, code, msg] = f.getStatus();
    std::cout << "Status: " << ok << ", " << code << ", " << msg << "\n";
    
    return 0;
}

11. 享元模式 (Flyweight)

意图:运用共享技术有效支持大量细粒度对象
场景:文字编辑器字符、游戏粒子

#include <iostream>
#include <unordered_map>
#include <memory>
#include <string_view>
#include <shared_mutex>
#include <mutex>

class TreeType {
public:
    TreeType(std::string_view n, std::string_view c) 
        : name_(n), color_(c) {}
    
    void draw(int x, int y) const {
        std::cout << name_ << " (" << color_ << ") at (" << x << ", " << y << ")\n";
    }

private:
    std::string name_;
    std::string color_;
};

// C++17: 线程安全享元工厂
template<typename T>
class FlyweightFactory {
public:
    std::shared_ptr<T> get(std::string_view key) {
        {
            std::shared_lock lock(mutex_);
            auto it = cache_.find(std::string(key));
            if (it != cache_.end()) return it->second;
        }
        
        std::unique_lock lock(mutex_);
        auto it = cache_.find(std::string(key));
        if (it != cache_.end()) return it->second;
        
        auto obj = std::make_shared<T>(key, "Green");
        cache_[std::string(key)] = obj;
        return obj;
    }

private:
    std::unordered_map<std::string, std::shared_ptr<T>> cache_;
    std::shared_mutex mutex_;
};

// C++17: inline变量的全局工厂
class TreeFactory {
public:
    static TreeFactory& instance() {
        static TreeFactory f;
        return f;
    }
    
    auto get(std::string_view name) {
        return factory_.get(name);
    }

private:
    TreeFactory() = default;
    FlyweightFactory<TreeType> factory_;
};

int main() {
    // 创建100棵树,实际只创建2种类型
    for (int i = 0; i < 50; ++i) {
        TreeFactory::instance().get("Oak");
    }
    for (int i = 0; i < 50; ++i) {
        TreeFactory::instance().get("Pine");
    }
    
    auto oak = TreeFactory::instance().get("Oak");
    oak->draw(10, 20);
    
    return 0;
}

12. 代理模式 (Proxy)

意图:为对象提供代理以控制访问
场景:延迟加载、访问控制、缓存

#include <iostream>
#include <memory>
#include <optional>
#include <functional>

class Subject {
public:
    virtual ~Subject() = default;
    virtual void request() = 0;
};

class RealSubject : public Subject {
public:
    RealSubject() { std::cout << "RealSubject created\n"; }
    void request() override { std::cout << "RealSubject request\n"; }
};

// 虚代理:延迟加载
class Proxy : public Subject {
public:
    void request() override {
        if (!realSubject_) {
            realSubject_ = std::make_unique<RealSubject>();
        }
        realSubject_->request();
    }

private:
    std::unique_ptr<RealSubject> realSubject_;
};

// C++17: 使用optional的延迟加载
template<typename T>
class Lazy {
public:
    explicit Lazy(std::function<std::unique_ptr<T>()> f) : factory_(f) {}
    
    T& get() {
        if (!instance_) instance_ = factory_();
        return *instance_;
    }

private:
    std::function<std::unique_ptr<T>()> factory_;
    std::unique_ptr<T> instance_;
};

int main() {
    Proxy proxy;
    std::cout << "Proxy created\n";
    proxy.request();  // 此时才创建RealSubject
    proxy.request();
    
    // Lazy代理
    Lazy<std::string> lazy([]() {
        std::cout << "Creating string...\n";
        return std::make_unique<std::string>("Hello");
    });
    std::cout << "Lazy created\n";
    std::cout << lazy.get() << "\n";
    
    return 0;
}

三、行为型模式

13. 责任链模式 (Chain of Responsibility)

意图:让多个对象有机会处理请求
场景:审批流程、事件处理

#include <iostream>
#include <functional>
#include <vector>
#include <optional>

// C++17: 使用折叠表达式的处理链
template<typename... Handlers>
class Chain {
public:
    explicit Chain(Handlers... h) : handlers_{h...} {}
    
    template<typename T>
    bool process(T&& req) {
        return (std::get<Handlers>(handlers_)(std::forward<T>(req)) || ...);
    }

private:
    std::tuple<Handlers...> handlers_;
};

// C++17: 使用optional的类型安全链
template<typename T>
class TypedChain {
public:
    using Handler = std::function<std::optional<T>(const T&)>;
    
    void add(Handler h) { handlers_.push_back(h); }
    
    std::optional<T> execute(const T& input) {
        T current = input;
        for (const auto& h : handlers_) {
            auto result = h(current);
            if (result) return result;
        }
        return std::nullopt;
    }

private:
    std::vector<Handler> handlers_;
};

int main() {
    auto h1 = [](int x) { 
        if (x < 10) { std::cout << "H1 handled " << x << "\n"; return true; }
        return false;
    };
    auto h2 = [](int x) {
        if (x < 100) { std::cout << "H2 handled " << x << "\n"; return true; }
        return false;
    };
    auto h3 = [](int x) {
        std::cout << "H3 (default) handled " << x << "\n";
        return true;
    };
    
    Chain chain(h1, h2, h3);
    chain.process(5);
    chain.process(50);
    chain.process(500);
    
    return 0;
}

14. 命令模式 (Command)

意图:将请求封装为对象
场景:撤销/重做、队列请求、事务

#include <iostream>
#include <functional>
#include <vector>
#include <stack>

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

// C++17: 使用lambda的命令
class LambdaCommand : public Command {
public:
    LambdaCommand(std::function<void()> exe, std::function<void()> undo)
        : execute_(exe), undo_(undo) {}
    
    void execute() override { execute_(); }
    void undo() override { undo_(); }

private:
    std::function<void()> execute_;
    std::function<void()> undo_;
};

// 宏命令
template<typename... Cmds>
class MacroCommand : public Command {
public:
    explicit MacroCommand(Cmds... cmds) : commands_{cmds...} {}
    
    void execute() override {
        std::apply([](auto&... cmd) { (cmd.execute(), ...); }, commands_);
    }
    
    void undo() override {
        std::apply([](auto&... cmd) { (cmd.undo(), ...); }, commands_);
    }

private:
    std::tuple<Cmds...> commands_;
};

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

private:
    std::stack<std::unique_ptr<Command>> history_;
};

int main() {
    int value = 0;
    
    Invoker invoker;
    
    // 使用lambda创建命令
    auto add = std::make_unique<LambdaCommand>(
        [&]() { value++; std::cout << "Add: " << value << "\n"; },
        [&]() { value--; std::cout << "Undo: " << value << "\n"; }
    );
    
    invoker.execute(std::move(add));
    invoker.undo();
    
    return 0;
}

15. 解释器模式 (Interpreter)

意图:定义文法表示和解释器
场景:DSL、规则引擎

#include <iostream>
#include <variant>
#include <string_view>
#include <unordered_map>
#include <functional>

using Value = std::variant<int, double, bool>;

class Context {
public:
    void set(std::string_view name, Value val) {
        vars_[std::string(name)] = val;
    }
    Value get(std::string_view name) const {
        auto it = vars_.find(std::string(name));
        return (it != vars_.end()) ? it->second : Value{0};
    }

private:
    std::unordered_map<std::string, Value> vars_;
};

// C++17: 使用visit的解释器
template<typename T>
T interpret(const Context& ctx, const std::variant<T, std::string_view>& expr) {
    return std::visit([&ctx](auto&& val) -> T {
        using U = std::decay_t<decltype(val)>;
        if constexpr (std::is_same_v<U, T>) {
            return val;
        } else {
            auto result = ctx.get(val);
            return std::get<T>(result);
        }
    }, expr);
}

// C++17: constexpr计算
constexpr int eval(char op, int a, int b) {
    switch (op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': return a / b;
        default: return 0;
    }
}

int main() {
    Context ctx;
    ctx.set("x", 10);
    ctx.set("y", 20);
    
    std::variant<int, std::string_view> expr = "x";
    std::cout << "Value: " << interpret<int>(ctx, expr) << "\n";
    
    constexpr int result = eval('+', 3, 5);
    std::cout << "3 + 5 = " << result << "\n";
    
    return 0;
}

16. 迭代器模式 (Iterator)

意图:顺序访问聚合对象元素
场景:自定义集合遍历

#include <iostream>
#include <vector>
#include <memory>

// C++17: 简化迭代器,使用范围for支持
template<typename T>
class Container {
public:
    void add(T val) { data_.push_back(std::move(val)); }
    
    // 标准迭代器接口
    auto begin() { return data_.begin(); }
    auto end() { return data_.end(); }
    auto begin() const { return data_.begin(); }
    auto end() const { return data_.end(); }
    
    // C++17: 结构化绑定支持
    auto getData() const { return std::make_tuple(data_.size(), data_.capacity()); }

private:
    std::vector<T> data_;
};

// C++17: 自定义范围
template<typename T>
class Range {
public:
    Range(T start, T end, T step = 1) 
        : start_(start), end_(end), step_(step) {}
    
    class Iterator {
    public:
        Iterator(T val, T step) : val_(val), step_(step) {}
        T operator*() const { return val_; }
        Iterator& operator++() { val_ += step_; return *this; }
        bool operator!=(const Iterator& o) const { return val_ < o.val_; }
    private:
        T val_, step_;
    };
    
    Iterator begin() const { return Iterator(start_, step_); }
    Iterator end() const { return Iterator(end_, step_); }

private:
    T start_, end_, step_;
};

int main() {
    Container<int> c;
    c.add(1);
    c.add(2);
    c.add(3);
    
    // 范围for
    for (auto& item : c) {
        std::cout << item << " ";
    }
    std::cout << "\n";
    
    // 结构化绑定
    auto [size, cap] = c.getData();
    std::cout << "Size: " << size << ", Cap: " << cap << "\n";
    
    // 自定义范围
    std::cout << "Range: ";
    for (auto i : Range(0, 10, 2)) {
        std::cout << i << " ";
    }
    std::cout << "\n";
    
    return 0;
}

17. 中介者模式 (Mediator)

意图:封装对象交互,减少耦合
场景:聊天室、机场调度、MVC控制器

#include <iostream>
#include <memory>
#include <vector>
#include <string>
#include <algorithm>

class Colleague;

class Mediator {
public:
    virtual ~Mediator() = default;
    virtual void send(const std::string& msg, Colleague* sender) = 0;
};

class Colleague {
public:
    explicit Colleague(Mediator* m) : mediator_(m) {}
    virtual ~Colleague() = default;
    
    void send(const std::string& msg) {
        mediator_->send(msg, this);
    }
    
    virtual void receive(const std::string& msg) = 0;
    void setName(std::string n) { name_ = std::move(n); }
    std::string getName() const { return name_; }

protected:
    Mediator* mediator_;
    std::string name_;
};

// C++17: 使用string_view优化
class ChatRoom : public Mediator {
public:
    void add(Colleague* c) { colleagues_.push_back(c); }
    
    void send(const std::string& msg, Colleague* sender) override {
        for (auto* c : colleagues_) {
            if (c != sender) {
                c->receive("[" + sender->getName() + "]: " + msg);
            }
        }
    }

private:
    std::vector<Colleague*> colleagues_;
};

class User : public Colleague {
public:
    using Colleague::Colleague;
    
    void receive(const std::string& msg) override {
        std::cout << name_ << " received: " << msg << "\n";
    }
};

int main() {
    ChatRoom room;
    
    User u1(&room);
    u1.setName("Alice");
    room.add(&u1);
    
    User u2(&room);
    u2.setName("Bob");
    room.add(&u2);
    
    User u3(&room);
    u3.setName("Charlie");
    room.add(&u3);
    
    u1.send("Hello everyone!");
    
    return 0;
}

18. 备忘录模式 (Memento)

意图:捕获对象状态以便恢复
场景:撤销操作、保存游戏、事务回滚

#include <iostream>
#include <string>
#include <vector>
#include <memory>

// C++17: 使用结构化绑定的备忘录
class Memento {
public:
    explicit Memento(std::string state) : state_(std::move(state)) {}
    std::string getState() const { return state_; }

private:
    std::string state_;
};

class Originator {
public:
    void setState(std::string s) { 
        state_ = std::move(s); 
        std::cout << "State set to: " << state_ << "\n";
    }
    
    std::string getState() const { return state_; }
    
    std::unique_ptr<Memento> save() {
        return std::make_unique<Memento>(state_);
    }
    
    void restore(const Memento* m) {
        state_ = m->getState();
        std::cout << "State restored to: " << state_ << "\n";
    }
    
    // C++17: 返回多个状态
    auto getDetails() const {
        return std::make_tuple(state_, state_.length());
    }

private:
    std::string state_;
};

class Caretaker {
public:
    void add(std::unique_ptr<Memento> m) {
        history_.push_back(std::move(m));
    }
    
    const Memento* get(size_t index) const {
        if (index < history_.size()) return history_[index].get();
        return nullptr;
    }
    
    void undo(Originator& o) {
        if (history_.size() > 1) {
            history_.pop_back();
            o.restore(history_.back().get());
        }
    }

private:
    std::vector<std::unique_ptr<Memento>> history_;
};

int main() {
    Originator originator;
    Caretaker caretaker;
    
    originator.setState("State1");
    caretaker.add(originator.save());
    
    originator.setState("State2");
    caretaker.add(originator.save());
    
    originator.setState("State3");
    
    // 撤销
    caretaker.undo(originator);
    
    // 结构化绑定
    auto [state, len] = originator.getDetails();
    std::cout << "Current: " << state << " (" << len << " chars)\n";
    
    return 0;
}

19. 观察者模式 (Observer)

意图:对象间一对多依赖,状态改变通知
场景:事件监听、消息订阅、MVC模式

#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
#include <string>

class Observer;

class Subject {
public:
    virtual ~Subject() = default;
    void attach(std::weak_ptr<Observer> o);
    void detach(std::weak_ptr<Observer> o);
    void notify();
    void setState(int s) { state_ = s; notify(); }
    int getState() const { return state_; }

private:
    std::vector<std::weak_ptr<Observer>> observers_;
    int state_ = 0;
};

class Observer : public std::enable_shared_from_this<Observer> {
public:
    virtual ~Observer() = default;
    virtual void update(int state) = 0;
    void subscribe(std::shared_ptr<Subject> s);
};

void Subject::attach(std::weak_ptr<Observer> o) {
    observers_.push_back(o);
}

void Subject::detach(std::weak_ptr<Observer> o) {
    observers_.erase(
        std::remove_if(observers_.begin(), observers_.end(),
            [&o](const std::weak_ptr<Observer>& obs) {
                return obs.lock() == o.lock();
            }),
        observers_.end()
    );
}

void Subject::notify() {
    for (auto it = observers_.begin(); it != observers_.end();) {
        if (auto obs = it->lock()) {
            obs->update(state_);
            ++it;
        } else {
            it = observers_.erase(it);  // 清理过期观察者
        }
    }
}

void Observer::subscribe(std::shared_ptr<Subject> s) {
    s->attach(weak_from_this());
}

class ConcreteObserver : public Observer {
public:
    explicit ConcreteObserver(std::string n) : name_(std::move(n)) {}
    void update(int state) override {
        std::cout << name_ << " received update: " << state << "\n";
    }
private:
    std::string name_;
};

int main() {
    auto subject = std::make_shared<Subject>();
    
    auto obs1 = std::make_shared<ConcreteObserver>("Observer1");
    auto obs2 = std::make_shared<ConcreteObserver>("Observer2");
    
    obs1->subscribe(subject);
    obs2->subscribe(subject);
    
    subject->setState(10);
    subject->setState(20);
    
    return 0;
}

20. 状态模式 (State)

意图:对象内部状态改变时改变行为
场景:状态机、游戏角色状态、订单状态

#include <iostream>
#include <memory>
#include <variant>
#include <functional>

class Context;

// C++17: 使用variant的状态
struct StateA;
struct StateB;

using State = std::variant<StateA, StateB>;

struct StateA {
    void handle(Context& ctx);
    std::string getName() const { return "StateA"; }
};

struct StateB {
    void handle(Context& ctx);
    std::string getName() const { return "StateB"; }
};

class Context {
public:
    Context() : state_(StateA{}) {}
    
    void request() {
        std::visit([this](auto& s) {
            s.handle(*this);
        }, state_);
    }
    
    void setState(State s) { state_ = std::move(s); }
    
    std::string getStateName() const {
        return std::visit([](const auto& s) { return s.getName(); }, state_);
    }

private:
    State state_;
};

void StateA::handle(Context& ctx) {
    std::cout << "StateA handling, switching to StateB\n";
    ctx.setState(StateB{});
}

void StateB::handle(Context& ctx) {
    std::cout << "StateB handling, switching to StateA\n";
    ctx.setState(StateA{});
}

// C++17: if constexpr的状态机
template<typename StateT>
class SimpleStateMachine {
public:
    void handle() {
        if constexpr (std::is_same_v<StateT, struct Idle>) {
            std::cout << "Idle state\n";
        } else if constexpr (std::is_same_v<StateT, struct Running>) {
            std::cout << "Running state\n";
        }
    }
};

struct Idle {};
struct Running {};

int main() {
    Context ctx;
    std::cout << "Initial: " << ctx.getStateName() << "\n";
    
    ctx.request();
    std::cout << "Current: " << ctx.getStateName() << "\n";
    
    ctx.request();
    std::cout << "Current: " << ctx.getStateName() << "\n";
    
    // if constexpr版本
    SimpleStateMachine<Idle> sm;
    sm.handle();
    
    return 0;
}

21. 策略模式 (Strategy)

意图:定义算法族,让它们可互相替换
场景:不同排序算法、支付方式、压缩算法

#include <iostream>
#include <memory>
#include <functional>
#include <vector>
#include <algorithm>
#include <numeric>

// C++17: 使用function的策略
class Context {
public:
    using Strategy = std::function<int(const std::vector<int>&)>;
    
    void setStrategy(Strategy s) { strategy_ = s; }
    
    int execute(const std::vector<int>& data) {
        return strategy_ ? strategy_(data) : 0;
    }

private:
    Strategy strategy_;
};

// 具体策略
int sumStrategy(const std::vector<int>& data) {
    return std::accumulate(data.begin(), data.end(), 0);
}

int maxStrategy(const std::vector<int>& data) {
    return *std::max_element(data.begin(), data.end());
}

// C++17: if constexpr的编译期策略
template<typename Strategy>
int process(const std::vector<int>& data) {
    if constexpr (std::is_same_v<Strategy, struct SumPolicy>) {
        return std::accumulate(data.begin(), data.end(), 0);
    } else if constexpr (std::is_same_v<Strategy, struct MaxPolicy>) {
        return *std::max_element(data.begin(), data.end());
    }
    return 0;
}

struct SumPolicy {};
struct MaxPolicy {};

int main() {
    Context ctx;
    std::vector<int> data = {1, 2, 3, 4, 5};
    
    // 运行时策略
    ctx.setStrategy(sumStrategy);
    std::cout << "Sum: " << ctx.execute(data) << "\n";
    
    ctx.setStrategy(maxStrategy);
    std::cout << "Max: " << ctx.execute(data) << "\n";
    
    // Lambda策略
    ctx.setStrategy([](const std::vector<int>& d) {
        return static_cast<int>(d.size());
    });
    std::cout << "Count: " << ctx.execute(data) << "\n";
    
    // 编译期策略
    std::cout << "Compile sum: " << process<SumPolicy>(data) << "\n";
    
    return 0;
}

22. 模板方法模式 (Template Method)

意图:定义算法骨架,子类重新定义步骤
场景:算法框架、数据处理流程

#include <iostream>
#include <string>

// 传统实现
class AbstractClass {
public:
    void templateMethod() {
        step1();
        step2();
        hook();
        step3();
    }
    
    virtual ~AbstractClass() = default;

protected:
    void step1() { std::cout << "Default step1\n"; }
    virtual void step2() = 0;
    virtual void step3() = 0;
    virtual void hook() {}  // 可选步骤
};

class ConcreteClass : public AbstractClass {
protected:
    void step2() override { std::cout << "Concrete step2\n"; }
    void step3() override { std::cout << "Concrete step3\n"; }
    void hook() override { std::cout << "Concrete hook\n"; }
};

// C++17: CRTP编译期多态
template<typename Derived>
class CRTPBase {
public:
    void algorithm() {
        static_cast<Derived*>(this)->step1();
        static_cast<Derived*>(this)->step2();
    }
    
protected:
    void defaultStep() { std::cout << "Default\n"; }
};

class Derived : public CRTPBase<Derived> {
public:
    void step1() { std::cout << "Derived step1\n"; }
    void step2() { std::cout << "Derived step2\n"; }
};

int main() {
    // 传统版本
    std::unique_ptr<AbstractClass> obj = std::make_unique<ConcreteClass>();
    obj->templateMethod();
    
    std::cout << "---\n";
    
    // CRTP版本
    CRTPBase<Derived> crtp;
    crtp.algorithm();
    
    return 0;
}

23. 访问者模式 (Visitor)

意图:在不改变类的前提下定义新操作
场景:编译器AST遍历、文档导出、报表生成

#include <iostream>
#include <variant>
#include <vector>
#include <memory>

// C++17: 使用variant替代双重分发
struct Circle { double radius; };
struct Rectangle { double w, h; };
struct Triangle { double a, b, c; };

using Shape = std::variant<Circle, Rectangle, Triangle>;

// 访问者:面积计算
class AreaVisitor {
public:
    double operator()(const Circle& c) const {
        return 3.14159 * c.radius * c.radius;
    }
    
    double operator()(const Rectangle& r) const {
        return r.w * r.h;
    }
    
    double operator()(const Triangle& t) const {
        // 海伦公式简化版
        return 0.5 * t.a * t.b;
    }
};

// 访问者:绘制
class DrawVisitor {
public:
    void operator()(const Circle&) const { std::cout << "Draw Circle\n"; }
    void operator()(const Rectangle&) const { std::cout << "Draw Rectangle\n"; }
    void operator()(const Triangle&) const { std::cout << "Draw Triangle\n"; }
};

// 使用访问者
void processShapes(const std::vector<Shape>& shapes) {
    AreaVisitor area;
    DrawVisitor draw;
    
    for (const auto& shape : shapes) {
        std::visit(draw, shape);
        double a = std::visit(area, shape);
        std::cout << "Area: " << a << "\n\n";
    }
}

// C++17: if constexpr的泛型访问
template<typename Visitor, typename... Shapes>
void visitAll(Visitor&& vis, Shapes&&... shapes) {
    (std::visit(std::forward<Visitor>(vis), std::forward<Shapes>(shapes)), ...);
}

int main() {
    std::vector<Shape> shapes;
    shapes.emplace_back(Circle{5.0});
    shapes.emplace_back(Rectangle{4.0, 6.0});
    shapes.emplace_back(Triangle{3.0, 4.0, 5.0});
    
    processShapes(shapes);
    
    return 0;
}

编译运行

所有代码使用以下命令编译:

g++ -std=c++17 -o pattern pattern.cpp

推荐: GCC 7+ 或 Clang 5+


版本: 3.0 | 纯 C++17 实现 | 全部23种模式完整代码


Edit page
Share this post on:

Previous Post
Ghostty + Yazi 现代终端配置指南
Next Post
leveldb源码阅读解析基础篇