策略模式 (Strategy Pattern)与几个C++例子

1. 模式定义与核心思想
策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端。

核心思想:

分离关注点:将算法的定义(怎么做)与算法的使用(什么时候做)分离开来。

面向接口编程:定义统一的算法接口,不同的算法实现该接口。

运行时灵活性:客户端可以在运行时动态地选择和使用不同的算法策略,而不需要修改客户端代码。

消除条件判断:用多态代替大量的 if-else 或 switch-case 语句。

2. 模式结构(角色分析)
策略模式包含三个核心角色:

Context (上下文)

维护一个对 Strategy 对象的引用。

可以定义一个接口来让 Strategy 访问它的数据。

通常用一个 ConcreteStrategy 对象来配置。

Strategy (策略接口)

定义所有支持的算法的公共接口。

Context 使用这个接口来调用具体的策略实现。

ConcreteStrategy (具体策略)

实现 Strategy 接口的具体算法。

每个具体策略类提供一种不同的算法实现。

协作关系:

Context 将客户端请求委派给当前配置的策略对象。

客户端通常创建并传递一个具体的策略对象给 Context。

Context 可以为其策略对象提供所需的数据。

3. 经典C++实现示例
示例 1:排序策略(经典示例)
展示如何使用不同的排序算法作为策略。

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

// Strategy: 排序策略接口
class SortStrategy {
public:
    virtual ~SortStrategy() = default;
    virtual void sort(std::vector<int>& data) const = 0;
    virtual std::string getName() const = 0;
};

// ConcreteStrategy: 快速排序
class QuickSort : public SortStrategy {
public:
    void sort(std::vector<int>& data) const override {
        std::cout << "Performing quick sort...\n";
        quickSort(data, 0, data.size() - 1);
    }

    std::string getName() const override { return "Quick Sort"; }

private:
    void quickSort(std::vector<int>& data, int low, int high) const {
        if (low < high) {
            int pi = partition(data, low, high);
            quickSort(data, low, pi - 1);
            quickSort(data, pi + 1, high);
        }
    }

    int partition(std::vector<int>& data, int low, int high) const {
        int pivot = data[high];
        int i = low - 1;
        
        for (int j = low; j < high; j++) {
            if (data[j] < pivot) {
                i++;
                std::swap(data[i], data[j]);
            }
        }
        std::swap(data[i + 1], data[high]);
        return i + 1;
    }
};

// ConcreteStrategy: 冒泡排序
class BubbleSort : public SortStrategy {
public:
    void sort(std::vector<int>& data) const override {
        std::cout << "Performing bubble sort...\n";
        for (size_t i = 0; i < data.size() - 1; i++) {
            for (size_t j = 0; j < data.size() - i - 1; j++) {
                if (data[j] > data[j + 1]) {
                    std::swap(data[j], data[j + 1]);
                }
            }
        }
    }

    std::string getName() const override { return "Bubble Sort"; }
};

// ConcreteStrategy: 标准库排序
class StdSort : public SortStrategy {
public:
    void sort(std::vector<int>& data) const override {
        std::cout << "Performing std::sort...\n";
        std::sort(data.begin(), data.end());
    }

    std::string getName() const override { return "Standard Library Sort"; }
};

// Context: 排序上下文
class Sorter {
private:
    std::unique_ptr<SortStrategy> strategy_;

public:
    explicit Sorter(std::unique_ptr<SortStrategy> strategy = nullptr) 
        : strategy_(std::move(strategy)) {}

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

    void sortData(std::vector<int>& data) const {
        if (strategy_) {
            std::cout << "Using strategy: " << strategy_->getName() << "\n";
            strategy_->sort(data);
        } else {
            std::cout << "No sorting strategy set!\n";
        }
    }
};

// 客户端代码
int main() {
    std::vector<int> data = {64, 34, 25, 12, 22, 11, 90};
    Sorter sorter;

    // 使用快速排序
    sorter.setStrategy(std::make_unique<QuickSort>());
    sorter.sortData(data);
    printData("After QuickSort:", data);

    // 重置数据,使用冒泡排序
    data = {64, 34, 25, 12, 22, 11, 90};
    sorter.setStrategy(std::make_unique<BubbleSort>());
    sorter.sortData(data);
    printData("After BubbleSort:", data);

    // 重置数据,使用标准库排序
    data = {64, 34, 25, 12, 22, 11, 90};
    sorter.setStrategy(std::make_unique<StdSort>());
    sorter.sortData(data);
    printData("After StdSort:", data);

    return 0;
}

void printData(const std::string& message, const std::vector<int>& data) {
    std::cout << message << " ";
    for (int num : data) std::cout << num << " ";
    std::cout << "\n\n";
}
示例 2:支付系统

展示电商系统中不同的支付方式作为策略。

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

// Strategy: 支付策略接口
class PaymentStrategy {
public:
    virtual ~PaymentStrategy() = default;
    virtual bool processPayment(double amount) const = 0;
    virtual std::string getName() const = 0;
};

// ConcreteStrategy: 信用卡支付
class CreditCardPayment : public PaymentStrategy {
public:
    bool processPayment(double amount) const override {
        std::cout << "Processing credit card payment of $" << amount << "\n";
        // 模拟支付处理逻辑
        std::cout << "Contacting bank... Verifying card... Transaction approved!\n";
        return true;
    }

    std::string getName() const override { return "Credit Card"; }
};

// ConcreteStrategy: PayPal支付
class PayPalPayment : public PaymentStrategy {
public:
    bool processPayment(double amount) const override {
        std::cout << "Processing PayPal payment of $" << amount << "\n";
        // 模拟支付处理逻辑
        std::cout << "Redirecting to PayPal... Login successful... Payment completed!\n";
        return true;
    }

    std::string getName() const override { return "PayPal"; }
};

// ConcreteStrategy: 加密货币支付
class CryptoPayment : public PaymentStrategy {
public:
    bool processPayment(double amount) const override {
        std::cout << "Processing cryptocurrency payment of $" << amount << "\n";
        // 模拟支付处理逻辑
        std::cout << "Verifying blockchain transaction... Confirmation received!\n";
        return true;
    }

    std::string getName() const override { return "Cryptocurrency"; }
};

// Context: 支付处理器
class PaymentProcessor {
private:
    std::unique_ptr<PaymentStrategy> strategy_;
    double amount_;

public:
    PaymentProcessor(double amount) : amount_(amount) {}

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

    void process() const {
        if (strategy_) {
            std::cout << "=== Processing payment via " << strategy_->getName() << " ===\n";
            bool success = strategy_->processPayment(amount_);
            if (success) {
                std::cout << "Payment successful!\n";
            } else {
                std::cout << "Payment failed!\n";
            }
            std::cout << "==============================\n\n";
        } else {
            std::cout << "No payment method selected!\n";
        }
    }
};

// 客户端代码
int main() {
    PaymentProcessor processor(99.99);

    // 使用信用卡支付
    processor.setPaymentStrategy(std::make_unique<CreditCardPayment>());
    processor.process();

    // 使用PayPal支付
    processor.setPaymentStrategy(std::make_unique<PayPalPayment>());
    processor.process();

    // 使用加密货币支付
    processor.setPaymentStrategy(std::make_unique<CryptoPayment>());
    processor.process();

    return 0;
}
示例 3:导航系统(路线计算)

展示不同的路线计算策略。

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

// Strategy: 路线策略接口
class RouteStrategy {
public:
    virtual ~RouteStrategy() = default;
    virtual void calculateRoute(const std::string& from, const std::string& to) const = 0;
    virtual std::string getName() const = 0;
};

// ConcreteStrategy: 最快路线
class FastestRoute : public RouteStrategy {
public:
    void calculateRoute(const std::string& from, const std::string& to) const override {
        std::cout << "Calculating fastest route from " << from << " to " << to << "\n";
        std::cout << "Analyzing traffic patterns... Avoiding congestion...\n";
        std::cout << "Fastest route: 15.2 km, 18 minutes\n";
    }

    std::string getName() const override { return "Fastest Route"; }
};

// ConcreteStrategy: 最短路线
class ShortestRoute : public RouteStrategy {
public:
    void calculateRoute(const std::string& from, const std::string& to) const override {
        std::cout << "Calculating shortest route from " << from << " to " << to << "\n";
        std::cout << "Finding minimum distance... Optimizing path...\n";
        std::cout << "Shortest route: 12.8 km, 22 minutes\n";
    }

    std::string getName() const override { return "Shortest Route"; }
};

// ConcreteStrategy: 最经济路线
class EcoRoute : public RouteStrategy {
public:
    void calculateRoute(const std::string& from, const std::string& to) const override {
        std::cout << "Calculating most economical route from " << from << " to " << to << "\n";
        std::cout << "Minimizing fuel consumption... Avoiding tolls...\n";
        std::cout << "Eco route: 14.5 km, 20 minutes, saves 15% fuel\n";
    }

    std::string getName() const override { return "Economical Route"; }
};

// ConcreteStrategy: 风景路线
class ScenicRoute : public RouteStrategy {
public:
    void calculateRoute(const std::string& from, const std::string& to) const override {
        std::cout << "Calculating scenic route from " << from << " to " << to << "\n";
        std::cout << "Including beautiful viewpoints... Avoiding highways...\n";
        std::cout << "Scenic route: 18.3 km, 30 minutes, 5 scenic spots\n";
    }

    std::string getName() const override { return "Scenic Route"; }
};

// Context: 导航系统
class NavigationSystem {
private:
    std::unique_ptr<RouteStrategy> strategy_;

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

    void navigate(const std::string& from, const std::string& to) const {
        if (strategy_) {
            std::cout << "\n=== " << strategy_->getName() << " ===\n";
            strategy_->calculateRoute(from, to);
            std::cout << "Navigation started... Follow the instructions.\n";
        } else {
            std::cout << "Please select a route strategy first!\n";
        }
    }
};

// 客户端代码
int main() {
    NavigationSystem nav;

    std::string from = "Home";
    std::string to = "Airport";

    // 不同的路线策略
    nav.setRouteStrategy(std::make_unique<FastestRoute>());
    nav.navigate(from, to);

    nav.setRouteStrategy(std::make_unique<ShortestRoute>());
    nav.navigate(from, to);

    nav.setRouteStrategy(std::make_unique<EcoRoute>());
    nav.navigate(from, to);

    nav.setRouteStrategy(std::make_unique<ScenicRoute>());
    nav.navigate(from, to);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值