2021-07-25

策略模式详解

最近公司培训聊到策略模式,打算记录下自己对策略模式的理解。先说下策略模式的概念:

  • 策略模式是一种定义一系列算法的方法,把使用算法的责任与算法本身分隔开,委派给不同的对象管理。

一般一个新概念出现都是为解决某个问题而诞生的,那策略模式是解决什么问题呢?最常见的就是平常我们在实际开发中需要做一些逻辑判断,而如果写的代码有很多if-else会让代码显得很臃肿,策略模式解决了这个问题。下面通过一个例子来详细理解策略模式:

场景:
一个商场收银软件,营业员根据客户所购买商品的单价和数量,向客户收费。

先来看个简单的例子:
// 声明一个变量计算总计
double total = 0.0d;

// 计算每个商品的价格
double totalPrice = 0.0d;

String[]  cbxType = {"正常收费", "打八折", "打七折"};

public void calculate(String cbxType, double price, double num){


        switch (cbxType){

            case "正常收费":
                totalPrice = price * num;
                break;
            case "打八折":
                totalPrice = (price * num) * 0.8;
                break;
            case "打七折":
                totalPrice = (price * num) * 0.7;
                break;
        }

    total = total + totalPrice;

    System.out.println("总计: "+ total+ "单价: "+ price+ "数量: "+ num);
}

public static void main(String[] args) {

    ClientMain p1 = new ClientMain();

    p1.calculate("打八折",100,8);
}

如果该商场需要增加新的打折优惠,那我们需要重新修改String数组中的代码和Switch中的条件,并且如果该商场又出其他优惠政策,判断的条件会越来越多。这样的方式完全是面向过程的思想写出的代码。
一个优秀的项目不会有特别强的耦合度,设计模式中对修改封闭对扩展开放的概念解决了这个问题。下面来用面向对象的思想结合策略模式来写该程序:

整体结构:
在这里插入图片描述

超类
在这里插入图片描述
策略1:
在这里插入图片描述
策略2:
在这里插入图片描述
策略3:

public class CashReturn extends CashSpuer{

// 达到返利条件值
public double moneyCondition = 0.0d;

// 返利值
public double moneyReturn = 0.0d;

public CashReturn(double moneyCondition, double moneyReturn){

    this.moneyCondition = moneyCondition;
    this.moneyReturn = moneyReturn;

}

@Override
public double acceptCash(double money) {
    double result = money;

    if(money > moneyCondition){
        result = money - (money / moneyCondition) * moneyReturn;
    }
    return result;
}

}

这里通过构造方法,传入具体的收费策略:

public class CashContext {

static CashSpuer cs = null;

public  CashContext(String type){

    switch (type){
        case "正常收费":
            CashNormal cn = new CashNormal();
            cs = cn;
            break;
        case "满300返100":
            CashReturn cr = new CashReturn(300,100);
            cs = cr;
            break;
        case "打8折":
            CashRebate cb = new CashRebate(0.8);
            cs = cb;
            break;
    }

}

public double GetResult(double money){
    return cs.acceptCash(money);
}

测试,可以看到实际操作的类只认识一个类就好了,如果再增加其他收费策略,我们只需扩展一个类并继承CashSuper父类就可以了,实现了对修改封闭对扩展开发的策略:
在这里插入图片描述
在这里插入图片描述

总结:策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。我们发现策略模式只是减少了具体实现类对象的压力,在CashContext依然有if判断,但没办法有需求就要改呀,任何需求的变更都是需要成本的。而且我们也要注意,不要为了技术而技术,面向对象的编程不是类越多越好,如果只是一个小需求还要用设计模式那就得不偿失了。类的划分是为了封装,分类的基础是抽象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值