从商场收银系统理解策略模式在代码设计中的优雅艺术

目录

1.业务场景

2.使用简单工厂模式来设计的弊端

2.1代码结构设计

 2.2 具体代码实现

2.3 使用简单工厂模式的弊端分析

3.使用策略实现商场收银系统对比简单工厂模式

3.1 策略模式的定义:

3.2 策略模式(strategy)结构图

3.3 基于策略模式实现商场收银系统的代码逻辑如下:

4.回顾


1.业务场景

在一个商场收银软件,需要实现商品的总价计算,并且满足在各种活动情况(打折、满减、返利),让我们来看下如何优雅的设计出这个功能。

2.使用简单工厂模式来设计的弊端

下面是简单工厂的代码实现;

2.1代码结构设计

 2.2 具体代码实现
/**
 * 收银抽象类;
 */
public abstract class CashSuper {

    /**
     * @param  money  原价
     * @return 当前价
     */
    public abstract double acceptCash(double money);
}
/**
 * 正常收费;
 */
class CashNormal extends CashSuper {

    /**
     * @param money 原价
     * @return 当前价
     */
    @Override
    public double acceptCash(double money) {
        return money;
    }
}
/**
 * 打折收费;
 */
class CashRebate extends CashSuper {

    private double moneyRebate = 1.0D;

    public void setMoneyRebate(double moneyRebate) {
        this.moneyRebate = moneyRebate;
    }

    /**
     * @param money 原价
     * @return 当前价
     */
    @Override
    public double acceptCash(double money) {

        return money * moneyRebate;
    }
}
/**
 * 返利收费;
 */
class CashReturn extends CashSuper {

    //返利条件
    private double moneyCondition;

    //返利金额
    private double moneyReturn;

    public void setMoneyCondition(double moneyCondition) {
        this.moneyCondition = moneyCondition;
    }

    public void setMoneyReturn(double moneyReturn) {
        this.moneyReturn = moneyReturn;
    }

    /**
     * @param money 原价
     * @return 当前价
     */
    @Override
    public double acceptCash(double money) {
        if (money >= moneyCondition && moneyCondition > 0) {
            return money - Math.floor(money/moneyCondition) * moneyReturn;
        }
        return money;
    }
}
/***
 * 收银工厂
 **/
class CashAcceptFactory {

    public static CashSuper createCashAccept(String type) {
        CashSuper cashSuper = null;
        switch (type) {
            case "正常收费":
                cashSuper = new CashNormal();
                break;
            case "满300减100":
                cashSuper = new CashReturn();
                break;
            case "打九折":
                cashSuper = new CashRebate();
                break;
            default:
                break;
        }
        return cashSuper;
    }
}
2.3 使用简单工厂模式的弊端分析

     如果业务稳定不变那这么实现也没有什么问题,但是业务是随市场的变化而变化的,所以这么实现的一个弊端,就是如果在加一种收费方式(满300积10积分),那么又要添加积分的子类,同时修改工厂类,这么扩展性不是很好。

3.使用策略实现商场收银系统对比简单工厂模式

3.1 策略模式的定义:

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

3.2 策略模式(strategy)结构图

3.3 基于策略模式实现商场收银系统的代码逻辑如下:
/**
 * 收银上下文
 */
public class CashContext {

    private CashSuper cashSuper;

    public CashContext(String type) {
        switch (type) {
            case "正常收费":
                cashSuper = new CashNormal();
                break;
            case "满300减100":
                cashSuper = new CashReturn();
                break;
            case "打九折":
                cashSuper = new CashRebate();
                break;
            default:
                break;
        }
    }

    /***
     *  获取计算结果
     **/
    public double getResult(double money) {

        return cashSuper.acceptCash(money);
    }
}

interface CashSuper {
    public double acceptCash(double money);
}

/**
 * 正常收费;
 */
class CashNormal implements CashSuper {

    /**
     * @param money 原价
     * @return 当前价
     */
    @Override
    public double acceptCash(double money) {
        return money;
    }
}

/**
 * 打折收费;
 */
class CashRebate implements CashSuper {

    private double moneyRebate = 1.0D;

    public void setMoneyRebate(double moneyRebate) {
        this.moneyRebate = moneyRebate;
    }

    /**
     * @param money 原价
     * @return 当前价
     */
    @Override
    public double acceptCash(double money) {

        return money * moneyRebate;
    }
}

/**
 * 返利收费;
 */
class CashReturn implements CashSuper {

    //返利条件
    private double moneyCondition;

    //返利金额
    private double moneyReturn;

    public void setMoneyCondition(double moneyCondition) {
        this.moneyCondition = moneyCondition;
    }

    public void setMoneyReturn(double moneyReturn) {
        this.moneyReturn = moneyReturn;
    }

    /**
     * @param money 原价
     * @return 当前价
     */
    @Override
    public double acceptCash(double money) {
        if (money >= moneyCondition && moneyCondition > 0) {
            return money - Math.floor(money / moneyCondition) * moneyReturn;
        }
        return money;
    }
}

4.回顾

 1. 策略模式简化了单元测试,因为每个算法都有自己单独的一个类。

 2. 如果使用抽象工厂的方式在CashContext中实现获取实例会让程序看起来更加的优雅,有艺术感。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

yongge

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

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

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

打赏作者

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

抵扣说明:

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

余额充值