设计模式实战:C++ 中观察者模式与策略模式的深度应用

设计模式是解决常见软件设计问题的可复用方案。在 C++ 中,观察者模式和策略模式是两种强大的行为模式,它们能提升代码的灵活性、可维护性和可扩展性。下面我将逐步解释这两种模式的深度应用,并提供实战代码示例。所有代码均基于标准 C++ 实现,确保真实可靠。

1. 观察者模式深度应用

观察者模式用于建立对象间的一对多依赖关系:当一个主题对象状态改变时,所有依赖它的观察者对象都会自动收到通知并更新。这种模式在事件驱动系统(如 GUI 框架或实时数据处理)中尤为有用。

深度应用点

  • 解耦主题和观察者:主题不需要知道观察者的具体实现,只需维护一个观察者列表。
  • 支持动态注册和注销:观察者可以随时加入或离开系统。
  • 扩展性强:易于添加新观察者类型,而无需修改主题代码。

实战示例:股票价格监控系统 假设我们构建一个股票交易系统,当股票价格变化时,通知所有订阅者(如交易员或分析工具)。以下是 C++ 实现:

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

// 观察者接口
class Observer {
public:
    virtual void update(const std::string& stockName, double price) = 0;
    virtual ~Observer() = default;
};

// 主题接口
class Subject {
public:
    virtual void registerObserver(Observer* observer) = 0;
    virtual void removeObserver(Observer* observer) = 0;
    virtual void notifyObservers() = 0;
    virtual ~Subject() = default;
};

// 具体主题:股票
class Stock : public Subject {
private:
    std::string name_;
    double price_;
    std::vector<Observer*> observers_;

public:
    Stock(const std::string& name, double price) : name_(name), price_(price) {}

    void setPrice(double price) {
        price_ = price;
        notifyObservers(); // 价格变化时通知所有观察者
    }

    void registerObserver(Observer* observer) override {
        observers_.push_back(observer);
    }

    void removeObserver(Observer* observer) override {
        observers_.erase(std::remove(observers_.begin(), observers_.end(), observer), observers_.end());
    }

    void notifyObservers() override {
        for (Observer* observer : observers_) {
            observer->update(name_, price_);
        }
    }
};

// 具体观察者:交易员
class Trader : public Observer {
private:
    std::string name_;

public:
    Trader(const std::string& name) : name_(name) {}

    void update(const std::string& stockName, double price) override {
        std::cout << "Trader " << name_ << ": Stock " << stockName << " price updated to $" << price << "\n";
    }
};

int main() {
    // 创建主题和观察者
    Stock appleStock("AAPL", 150.0);
    Trader trader1("Alice");
    Trader trader2("Bob");

    // 注册观察者
    appleStock.registerObserver(&trader1);
    appleStock.registerObserver(&trader2);

    // 模拟价格变化
    appleStock.setPrice(155.0); // 所有观察者收到通知
    appleStock.setPrice(160.0);

    // 移除一个观察者
    appleStock.removeObserver(&trader2);
    appleStock.setPrice(165.0); // 只有 Alice 收到通知

    return 0;
}

深度应用分析

  • 动态管理:在运行时添加或移除观察者(如 removeObserver),适应实时需求。
  • 性能优化:可使用智能指针(如 std::shared_ptr)管理观察者生命周期,避免内存泄漏。
  • 扩展场景:结合其他模式,如使用工厂模式创建观察者,或添加过滤逻辑(只通知特定条件观察者)。
2. 策略模式深度应用

策略模式定义了一系列算法,封装每个算法,并使它们可互换。策略模式让算法独立于客户端变化,适用于需要动态切换行为的场景,如支付系统或排序算法。

深度应用点

  • 算法封装:每个策略类实现一个独立算法,便于测试和复用。
  • 运行时切换:客户端可以动态改变策略,无需重新编译。
  • 减少条件语句:避免庞大的 if-else 结构,提升代码可读性。

实战示例:支付处理系统 假设我们开发一个电商平台,支持多种支付方式(如信用卡、PayPal)。以下是 C++ 实现:

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

// 策略接口:支付策略
class PaymentStrategy {
public:
    virtual void pay(double amount) = 0;
    virtual ~PaymentStrategy() = default;
};

// 具体策略:信用卡支付
class CreditCardPayment : public PaymentStrategy {
private:
    std::string cardNumber_;

public:
    CreditCardPayment(const std::string& cardNumber) : cardNumber_(cardNumber) {}

    void pay(double amount) override {
        std::cout << "Paid $" << amount << " via Credit Card ending with " 
                  << cardNumber_.substr(cardNumber_.size() - 4) << "\n";
    }
};

// 具体策略:PayPal支付
class PayPalPayment : public PaymentStrategy {
private:
    std::string email_;

public:
    PayPalPayment(const std::string& email) : email_(email) {}

    void pay(double amount) override {
        std::cout << "Paid $" << amount << " via PayPal account: " << email_ << "\n";
    }
};

// 上下文类:支付处理器
class PaymentProcessor {
private:
    std::unique_ptr<PaymentStrategy> strategy_;

public:
    void setStrategy(std::unique_ptr<PaymentStrategy> strategy) {
        strategy_ = std::move(strategy);
    }

    void executePayment(double amount) {
        if (strategy_) {
            strategy_->pay(amount);
        } else {
            std::cout << "No payment strategy set!\n";
        }
    }
};

int main() {
    // 创建策略和上下文
    PaymentProcessor processor;
    
    // 设置信用卡策略
    processor.setStrategy(std::make_unique<CreditCardPayment>("1234567890123456"));
    processor.executePayment(100.0); // 输出信用卡支付信息

    // 切换到 PayPal 策略
    processor.setStrategy(std::make_unique<PayPalPayment>("user@example.com"));
    processor.executePayment(50.0); // 输出 PayPal 支付信息

    return 0;
}

深度应用分析

  • 策略组合:策略可以嵌套,例如一个策略使用另一个策略(如折扣策略 + 支付策略)。
  • 依赖注入:通过构造函数或 setter 注入策略,支持单元测试。
  • 性能考虑:使用智能指针(如 std::unique_ptr)管理策略生命周期,确保资源安全。
3. 结合观察者模式与策略模式的深度应用

在复杂系统中,观察者模式和策略模式可以协同工作,实现更强大的功能。例如,构建一个智能交易系统:当市场数据变化(观察者模式),系统自动切换交易策略(策略模式)。

实战示例:智能交易引擎 以下是一个简化版实现,结合两种模式:

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

// 观察者模式部分
class MarketDataSubject; // 前向声明

class MarketObserver {
public:
    virtual void update(double price) = 0;
    virtual ~MarketObserver() = default;
};

class MarketDataSubject {
private:
    double price_;
    std::vector<MarketObserver*> observers_;

public:
    void setPrice(double price) {
        price_ = price;
        notifyObservers();
    }

    void registerObserver(MarketObserver* observer) {
        observers_.push_back(observer);
    }

    void removeObserver(MarketObserver* observer) {
        observers_.erase(std::remove(observers_.begin(), observers_.end(), observer), observers_.end());
    }

    void notifyObservers() {
        for (auto* observer : observers_) {
            observer->update(price_);
        }
    }
};

// 策略模式部分
class TradingStrategy {
public:
    virtual void executeTrade(double price) = 0;
    virtual ~TradingStrategy() = default;
};

class BuyStrategy : public TradingStrategy {
public:
    void executeTrade(double price) override {
        std::cout << "Executing BUY order at price $" << price << "\n";
    }
};

class SellStrategy : public TradingStrategy {
public:
    void executeTrade(double price) override {
        std::cout << "Executing SELL order at price $" << price << "\n";
    }
};

// 结合类:交易引擎(既是观察者又是策略上下文)
class TradingEngine : public MarketObserver {
private:
    std::unique_ptr<TradingStrategy> strategy_;
    MarketDataSubject& subject_;

public:
    TradingEngine(MarketDataSubject& subject) : subject_(subject) {
        subject_.registerObserver(this);
    }

    ~TradingEngine() {
        subject_.removeObserver(this);
    }

    void setStrategy(std::unique_ptr<TradingStrategy> strategy) {
        strategy_ = std::move(strategy);
    }

    void update(double price) override {
        if (strategy_) {
            strategy_->executeTrade(price);
        }
    }
};

int main() {
    // 创建主题
    MarketDataSubject market;
    
    // 创建交易引擎并设置初始策略
    TradingEngine engine(market);
    engine.setStrategy(std::make_unique<BuyStrategy>());

    // 模拟市场变化
    market.setPrice(150.0); // 触发 BUY 策略
    engine.setStrategy(std::make_unique<SellStrategy>());
    market.setPrice(145.0); // 触发 SELL 策略

    return 0;
}

深度应用分析

  • 事件驱动策略切换:观察者模式捕获事件(如价格变化),触发策略执行,实现自动化决策。
  • 资源管理:使用 RAII(资源获取即初始化)原则确保对象安全(如 TradingEngine 在析构时注销观察者)。
  • 可扩展性:易于添加新策略或观察者,例如添加一个风险控制策略,在价格波动大时切换策略。
4. 总结

在 C++ 中,观察者模式和策略模式的深度应用能显著提升系统设计质量:

  • 观察者模式:适用于事件通知场景,通过解耦主题和观察者,支持动态响应。
  • 策略模式:适用于算法切换场景,通过封装策略,实现灵活的行为变化。
  • 结合应用:在复杂系统中(如金融交易或游戏引擎),两种模式协同工作,提供高度模块化和可维护的架构。

最佳实践建议:

  • 使用智能指针管理资源,避免内存泄漏。
  • 定义清晰的接口,确保模式间的松耦合。
  • 在性能关键场景,优化通知机制(如使用异步通知)。

通过这些实战示例,您可以在实际项目中应用这些模式,构建更健壮的 C++ 系统。如果您有具体场景或问题,我可以进一步细化解释!

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐