【设计模式】—五大创建型之策略模式

五大创建型设计模式:

单例模式,策略模式,观察者模式,工厂模式,原型模式

策略模式(Strategy Pattern)
        策略模式是行为型设计模式,用于定义一系列算法,封装每个算法,并使它们可以互相替换。它让算法独立于使用它的客户端而变化,是面试中高频考察的设计模式之一。

1. 核心概念(背!)
        意图:将算法的使用与实现分离,避免多重条件判断,支持开闭原则。
        角色:
        策略接口(Strategy):定义算法的公共接口。
        具体策略(Concrete Strategy):实现策略接口的具体算法。
        上下文(Context):持有一个策略对象的引用,通过接口调用算法。

2. 代码示例
        场景:电商促销活动,支持多种折扣策略(无折扣、满减、百分比折扣)。

#include <iostream>
#include <memory>

// 1. 策略接口(抽象类)
class DiscountStrategy {
public:
    virtual ~DiscountStrategy() = default;  // 虚析构确保正确释放资源
    virtual double applyDiscount(double originalPrice) const = 0;
};

// 2. 具体策略实现
class NoDiscount : public DiscountStrategy {
public:
    double applyDiscount(double price) const override {
        return price;
    }
};

class FullReductionDiscount : public DiscountStrategy {
private:
    double full_;
    double reduction_;
public:
    FullReductionDiscount(double full, double reduction) 
        : full_(full), reduction_(reduction) {}

    double applyDiscount(double price) const override {
        return (price >= full_) ? (price - reduction_) : price;
    }
};

class PercentageDiscount : public DiscountStrategy {
private:
    double percentage_;
public:
    explicit PercentageDiscount(double percentage) 
        : percentage_(percentage) {}

    double applyDiscount(double price) const override {
        return price * (1 - percentage_);
    }
};

// 3. 上下文(订单类)
class Order {
private:
    std::unique_ptr<DiscountStrategy> strategy_;  // 使用智能指针管理策略对象
    double price_;
public:
    Order(double price) : price_(price) {}

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

    double checkout() const {
        if (!strategy_) {
            throw std::runtime_error("Discount strategy not set!");
        }
        return strategy_->applyDiscount(price_);
    }
};

// 4. 客户端使用
int main() {
    Order order(1000.0);

    // 设置满减策略:满1000减200
    order.setStrategy(std::make_unique<FullReductionDiscount>(1000, 200));
    std::cout << "Full Reduction Discount: " << order.checkout() << std::endl;  // 输出800

    // 切换为百分比折扣:10% off
    order.setStrategy(std::make_unique<PercentageDiscount>(0.1));
    std::cout << "Percentage Discount: " << order.checkout() << std::endl;       // 输出900

    return 0;
}

3. C++ 实现关键点
        智能指针管理资源:
        使用 std::unique_ptr 持有策略对象,避免手动 new/delete,防止内存泄漏。
        std::move 转移所有权,确保策略对象生命周期与订单一致。


        虚析构函数:
        virtual ~DiscountStrategy() = default;
        基类声明虚析构函数,确保子类对象通过基类指针销毁时正确释放资源。


        常量正确性:
        virtual double applyDiscount(double originalPrice) const = 0;
        const 修饰成员函数,承诺不修改对象状态,提高代码安全性。


        异常处理:
        if (!strategy_) {
            throw std::runtime_error("Discount strategy not set!");
        }
        检查策略是否已设置,避免空指针访问。


4. 策略模式在C++中的优势
        零成本抽象:C++的策略模式通过虚函数实现动态多态,性能接近手写条件判断。
        编译时检查:类型安全,避免运行时类型错误。
        与现代C++特性结合:可结合模板、Lambda等实现更灵活的策略(见下文扩展)。


5. 扩展:使用Lambda和模板实现策略模式(C++11+)
        若策略简单且无状态,可直接用 std::function 替代抽象类:

#include <functional>

class Order {
private:
    std::function<double(double)> strategy_;  // 策略为函数对象
    double price_;
public:
    Order(double price) : price_(price) {}

    void setStrategy(std::function<double(double)> strategy) {
        strategy_ = strategy;
    }

    double checkout() const {
        if (!strategy_) {
            throw std::runtime_error("Strategy not set!");
        }
        return strategy_(price_);
    }
};

// 客户端使用
int main() {
    Order order(1000.0);

    // 设置满减策略(Lambda表达式)
    order.setStrategy([](double price) {
        return (price >= 1000) ? (price - 200) : price;
    });
    std::cout << "Lambda Strategy: " << order.checkout() << std::endl;  // 输出800

    return 0;
}

6. 面试常见问题
Q1:C++中如何避免策略对象的内存泄漏?
        答:使用智能指针(如 std::unique_ptr 或 std::shared_ptr)自动管理资源,避免手动 delete。
Q2:策略模式与模板方法模式的区别?
        答:策略模式:通过组合(持有策略对象)实现算法扩展,运行时动态切换。
        模板方法模式:通过继承(子类重写虚方法)实现算法扩展,编译时确定行为。
Q3:是否所有策略都需继承自同一个基类?
        答:不一定。C++中可通过模板参数或 std::function 实现“鸭子类型”,只要策略对象满足特定接口即可(如拥有 applyDiscount 方法)。

 

总结
在C++中实现策略模式时,需注意:

资源管理:优先使用智能指针。
多态机制:虚函数实现运行时多态。
现代C++特性:结合Lambda、模板等简化代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小新阿呆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值