策略模式

1. 模式定义

策略模式(Strategy Pattern): 定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy)。

如下图, 用Context把算法聚合起来
在这里插入图片描述

2. 例子

  1. 类图
    CashContext把算法抽象起来.
    在这里插入图片描述

  2. 代码

    /*
     * @Author: sanjayzhong
     * @Github: https://github.com/sanjayzzzhong
     * @Date: 2019-12-04 14:03:40
     */
    //需求: 给出单价和数量, 求出每种商品的费用
    //后续会对商品进行打折
    //还会有促销: 如满100-30等策略
    #include <iostream>
    #include <string>
    using namespace std;
    
    class CashSuper
    { //收费父类
    public:
        virtual double AcceptCash(double money) = 0;
    };
    
    //正常收费子类
    class CashNormal : public CashSuper
    {
    public:
        virtual double AcceptCash(double money) override
        {
            return money;
        }
    };
    
    //打折收费子类
    class CashRebate : public CashSuper
    {
    public:
        double m_rebate_rate = 1.0; //打折率默认为1
        CashRebate(double rate) : m_rebate_rate(rate) {}
        virtual double AcceptCash(double money) override
        {
            return money * m_rebate_rate;
        }
    };
    
    //返利收费子类
    class CashReturn : public CashSuper
    {
    public:
        double m_condition = 0;
        double m_return = 0;
        CashReturn(double condition, double money_return) : m_condition(condition), m_return(money_return) {}
        virtual double AcceptCash(double money) override
        {
            double result = money;
            if (money >= m_condition)
            {
                result -= m_return;
            }
            return result;
        }
    };
    
    //context类
    class CashContext
    {
    public:
        CashSuper *m_cs = nullptr;
        CashContext(CashSuper *cs) : m_cs(cs)
        {
        }
        double GetResult(double money)
        {
            return m_cs->AcceptCash(money);
        }
    };
    
    
    //这里是暴露给客户端的接口
    int main(int argc, char const *argv[])
    {
        CashContext *cc = nullptr;
        cout << "请选择收费模式: 1. 正常收费\t2. 满300返100\t3.打8折" << endl;
        int choice;
        cin >> choice;
        switch (choice)
        {
        case 1:
            cc = new CashContext(new CashNormal);
            break;
        
        case 2:
            cc = new CashContext(new CashReturn(300, 100));
            break;
        case 3:
            cc = new CashContext(new CashRebate(0.8));
            break;
        }
        cout << "输入物品单价和数量, 用空格分开: " << endl;
        int price, num;
        cin >> price >> num;
        double result = cc->GetResult(price * num);
        cout << "原价为: " << price * num << ", 经过打折后价格为: " << result << endl;
    
        return 0;
    }
    
  3. 简单工厂模式对比
    如果上述需求用简单工厂模式来实现的话, 是怎么样?
    如下图: 每种打折算法继承于CashSuper, 然后通过工厂来实例化每个特定的算法.
    如果需要新增算法, 需要增加新的继承类, 同时需要在工厂里增加新的判断条件.

而策略模式:
context把算法聚合起来, 让客户端调用的时候调用统一的context的接口, 然后运行时再动态绑定, 调用相应的算法.

总体来说, 策略模式的稳定部分是: cashsuper+context, 简单工厂模式的稳定部分是:cashsuper部分.
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zedjay_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值