程杰版的是用c#写的,通过学习,用java实现收银台代码
老套路,第一步还是封装接口
CashSuper现金收取接口,这是没有用抽象方法,其实抽象方法是接口的另一种表达
public interface CashSuper {
/**
* 接口定义方法,收取现金,参数为原价,返回当前价
*/
BigDecimal acceptCash(BigDecimal money);
}
下面是各种收费模式的实现,都实现CashSuper现金收取接口
CashNormal 正常收费,直接返回原价
public class CashNormal implements CashSuper {
/**
* 正常收费,原价返回
*/
@Override
public BigDecimal acceptCash(BigDecimal money) {
return money;
}
}
CashRebate 打折收费, 写一个有参数的构造方法,初始化时把折扣率传入。
public class CashRebate implements CashSuper {
private BigDecimal moneyRebate = new BigDecimal(1);
/**
* 打折收费构造方法,初始化时,必须输入折扣率 如8折,就是0.8
*/
public CashRebate(BigDecimal moneyRebate) {
this.moneyRebate = moneyRebate;
}
@Override
public BigDecimal acceptCash(BigDecimal money) {
return money.multiply(moneyRebate);
}
}
CashReturn 返利收费,也是写一个有参数的构造方法, 初始化时必须输入返利条件,比如满300减100 就是moneyCondition = 300,moneyReturn = 100
public class CashReturn implements CashSuper {
private BigDecimal moneyCondition = new BigDecimal(0);
private BigDecimal moneyReturn = new BigDecimal(0);
/**
* 返利收费,初始化时必须输入返利条件,比如满300减100 就是moneyCondition = 300,moneyReturn = 100
*/
public CashReturn(BigDecimal moneyCondition, BigDecimal moneyReturn) {
this.moneyCondition = moneyCondition;
this.moneyReturn = moneyReturn;
}
@Override
public BigDecimal acceptCash(BigDecimal money) {
BigDecimal result = money;
// 若大于条件,减去返利金额
if (money.compareTo(moneyCondition) == 1) {
result = money.subtract(moneyReturn);
}
return result;
}
}
最后写一个CashContext,这是策略模式与工程模式的结合
public class CashContext {
// 声明一个CashSuper对象
private CashSuper cs;
/**
* 传入的参数为收费类型,不是收费策略对象
*/
public CashContext(String type) {
switch (type) {
case "正常收费":
cs = new CashNormal();
break;
case "打8折":
cs = new CashRebate(new BigDecimal(0.8));
break;
case "满300减100":
cs = new CashReturn(new BigDecimal(300), new BigDecimal(100));
break;
default:
break;
}
}
public BigDecimal getResult(BigDecimal money) {
return cs.acceptCash(money);
}
}
同时写一个有参数的构造方法,初始化时,通过传入不同的收费类型,实例化具体的策略,这是工厂模式的简单应用,最后有客户端调用getResult方法,返回收费结果。
Main 客户端代码
public class Main {
public static void main(String[] args) {
CashContext context = new CashContext("满300减100");
BigDecimal result = context.getResult(new BigDecimal(500));
System.out.println(result);
}
}
总结
- 策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所以的算法,减少了各种算法类与使用算法类之间的耦合
- 策略模式的Startegy类层为Context定义了一系列的可供重用的算法或行为。继承有助于吸取出这些算法中的公共功能
- 在基本的策略模式中,选择所用具体实现的职责有客户端对象承担,并转给策略模式的Context对象。
- 策略模式是用来封装算法的,但在实践中,我们发现可以用它来分装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑用策略模式来处理这种变化的可能性