设计模式—策略模式

与其明天开始,不如现在行动!


策略模式—商场促销

策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。

现在有一个商场需要一个收银系统,根据客户所买商品的单价和数量来收费。商场总共有三种销售模式:

  1. 第一种是全部商品原价收费
  2. 第二种是全部打八折处理
  3. 第三种是满300返利100

此时可以根据简单工厂模式,收银员只需要输入当前销售模式,让程序自己判断使用哪种计算方式。

抽象收费类:

public abstract class CashSuper {
   
    public abstract double acceptCash(double price, int num);
}

正常收费类:

public class CashNormal extends CashSuper{
   
    @Override
    public double acceptCash(double price, int num) {
   
        return price * num;
    }
}

打折收费类:

public class CashRebate extends CashSuper{
   
    private double moneyRebate = 1;
    //初始化时候要输入打折率
    public CashRebate(double moneyRebate) {
   
        this.moneyRebate = moneyRebate;
    }

    @Override
    public double acceptCash(double price, int num) {
   
        return price * moneyRebate * num;
    }
}

返利收费类:

public class CashReturn extends CashSuper{
   
    //返利条件
    private double moneyCondition = 0;
    //返利值
    private double moneyReturn = 0;

    public CashReturn(double moneyCondition, double moneyReturn) {
   
        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }
    @Override
    public double acceptCash(double price, int num) {
   
        double res = price * num;
        if (moneyCondition > 0 && res >= moneyCondition) {
   
            res = res - Math.floor(res / moneyCondition) * moneyReturn;
        }
        return res;
    }
}

收费对象生成工厂:

public class CashFactory {
   
    public static CashSuper createCashAccept(int cashType) {
   
        CashSuper cashSuper = null;
        switch (cashType) {
   
            case 1:  //正常收费
                cashSuper = new CashNormal();
                break;
            case 2:  //打八折收费
                cashSuper = new CashRebate(0.8);
                break;
            case 3:  //满300返利100
                cashSuper = new CashReturn(300, 100);
                break;
        }
        return cashSuper;
    }
}

界面逻辑:

public class Main {
   
    public static void main(String[] args) {
   
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入当前销售模式:1:无促销,2:打折,3:返利");
        int cashType = Integer.parseInt(sc.nextLine()); //商品销售模式
        System.out.println("请输入当前商品单价:");
        double price = Double.parseDouble(sc.nextLine()); //商品单价
        System.out.println("请输入当前商品数量:");
        int num = Integer.parseInt(sc.nextLine()); //商品数量
        double totalPrice = 0; //当前商品价格

        CashSuper cashSuper = CashFactory.createCashAccept(cashType);
        totalPrice = cashSuper.acceptCash(price, num);

        System.out.println("商品总价为:" + totalPrice + "元");
    }
}

当前程序结构图:

image-20231215195127230

虽然此时我们解决了对象的创建问题,但是商场是一个经常性更改折扣额度和返利额度的地方,如果每次都要重新编译部署,这种方式实在是太繁琐了,所以简单工厂不是最好的,这个时候就应该使用策略模式,让这些促销方式封装起来,让他们之间可以相互替换。

改造简单工厂为策略模式,首先把工厂类删除,改造后的程序:

新增收费上下文类:

public class CashContext {
   
    private CashSuper cashSuper;
    public CashContext(int  cashType) {
   
        switch (cashType) {
   
            case 1:  //正常收费
                cashSuper = new CashNormal();
                break;
            case 2:  //打八折收费
                cashSuper = new CashRebate(0.8);
                break;
            case 3:  //满300返利100
                cashSuper = new CashReturn(300, 100);
                break;
        }
    }

    public double getResult(double price, int num) {
   
        return cashSuper.acceptCash(price, num);
    }
}

界面逻辑改造:

public class Main {
   
    public static void main(String[] args) {
   
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入当前销售模式:1:无促销,2:打八折,3:满300返100");
        int cashType = Integer.parseInt(sc.nextLine()); //商品销售模式
        System.out.println("请输入当前商品单价:");
        double price = Double.parseDouble(sc.nextLine()); //商品单价
        System.out.println("请输入当前商品数量:");
        int num = Integer.parseInt(sc.nextLine()); //商品数量
        double totalPrice = 0; //当前商品价格

        totalPrice = new CashContext(cashType).getResult(price, num);

        System.out.println("商品总价为:" + totalPrice + "元");
    }
}

当前程序结构图:

image-20231215203555097

简单工厂模式:我需要让界面也就是客户端,认识两个类:CashSuper和CashFactory

策略模式与简单工厂结合:客户端只需要认识一个类:CashContext

总结:

策略模式是定义一系列算法的方法,从用途上,他们完成的是相同的工作,只是具体的实现有所不同,优点:

  1. 策略模式可以用相同的方式调用所有的算法,减少了各类算法类与使用算法类的耦合。
  2. 而且策略模式可以对每个算法类进行单独的测试,同时修改任何一个算法类也不影响其它算法类。

总的来说,策略模式封装了变化,只要在分析过程中需要再不同的时间或者场景下用不同的规则,此时就可以考虑用策略模式实现的可能性。


💎总结

本文中若是有出现的错误请在评论区或者私信指出,我再进行改正优化,如果文章对你有所帮助,请给博主一个宝贵的三连,感谢大家😘!!!


相关推荐

  1. 设计模式——策略模式

    2023-12-16 07:34:06       30 阅读
  2. 设计模式-策略模式

    2023-12-16 07:34:06       38 阅读
  3. 设计模式——策略模式

    2023-12-16 07:34:06       29 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-16 07:34:06       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-16 07:34:06       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-16 07:34:06       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-16 07:34:06       20 阅读

热门阅读

  1. flutter学习-day11-容器类组件

    2023-12-16 07:34:06       38 阅读
  2. 【Hadoop】WordCount源码分析

    2023-12-16 07:34:06       43 阅读
  3. Spring Boot中实现邮件推送

    2023-12-16 07:34:06       35 阅读
  4. 飞天使-实际运用安装rabbitmq

    2023-12-16 07:34:06       40 阅读
  5. 单片机Freertos入门(二)任务调度的介绍

    2023-12-16 07:34:06       33 阅读
  6. Stable Diffusion的数学原理

    2023-12-16 07:34:06       34 阅读
  7. QT 记录

    2023-12-16 07:34:06       44 阅读
  8. Kafka Avro序列化之一:使用自定义序列化

    2023-12-16 07:34:06       46 阅读
  9. isRef、unRef、toRef、toRefs、shallowRef

    2023-12-16 07:34:06       39 阅读
  10. g++/git/vim相关学习笔记

    2023-12-16 07:34:06       39 阅读
  11. linux定时任务

    2023-12-16 07:34:06       39 阅读
  12. 电学基础名词

    2023-12-16 07:34:06       38 阅读
  13. html 基础学习笔记

    2023-12-16 07:34:06       31 阅读