策略模式
某日张三中了注30倍的双色球一等奖,张三为此结束了自己的程序员的职业生涯,挥霍几日后突发奇想,想开个商场,过某日商场开业,张三心血来潮想写代码,正巧碰上了自己家的商场有各种活动,随即兴起写个商场促销的业务代码。
业务
自家商场打折 部分规则如下:
有的商品不打折 原价,部分商品 满500减200 另有之八五折。
代码撸开~ 在写时想到前几天 的一个文章简单工厂模式感觉可行随后吭哧吭哧撸开。。。
代码:
公共抽象类
public abstract class CashSupper {
/**
* 计算结果
* @param money 原价
* @return 结果
*/
public abstract double acceptCash(double money);
}
正常收费业务
打折收费业务
public class CashRebate extends CashSupper {
private double moneyRebate = 1D;
/**
* 构造
* @param moneyRebate 打折率
*/
public CashRebate(double moneyRebate) {
this.moneyRebate = moneyRebate;
}
@Override
public double acceptCash(double money) {
return money * moneyRebate;
}
}
满减收费业务
public class CashReturn extends CashSupper {
/**
* 满足条件金额
*/
private double monetCondition;
/**
* 满足条件后返利金额
*/
private double moneyReturn;
/**
* 构造
* @param monetCondition 满足条件金额
* @param moneyReturn 满足条件后返利金额
*/
public CashReturn(double monetCondition, double moneyReturn) {
this.monetCondition = monetCondition;
this.moneyReturn = moneyReturn;
}
@Override
public double acceptCash(double money) {
double result = money;
if (money >= monetCondition) {
result = money - moneyReturn;
}
return result;
}
}
简单工厂
public class CashFactory {
public static CashSupper getCashAccept(String type){
CashSupper supper = null;
switch (type) {
case "正常收费" :
supper = new CashNormal();
break;
case "满300减100" :
supper = new CashReturn(300, 100);
break;
case "八折活动" :
supper = new CashRebate(0.8);
break;
default:
}
return supper;
}
}
执行
public class Run {
public static void main(String[] args) {
CashSupper cashSupper = CashFactory.getCashAccept("正常收费");
System.out.println("正常收费:"+cashSupper.acceptCash(400));
CashSupper cashSupper1 = CashFactory.getCashAccept("满300减100");
System.out.println("满300减100:"+cashSupper1.acceptCash(400));
CashSupper cashSupper2 = CashFactory.getCashAccept("八折活动");
System.out.println("八折活动:"+cashSupper2.acceptCash(400));
}
}
作为老板的张三撸完代码后发现一个很头痛的问题,现在的业务相对来说并不是特别的复杂,如果遇到十月一双十一这种业务复杂的时间段的话,业务肯定的繁重,于是搜集资料经过研究发现可以对其进行结构化的优化使用 策略模式搭配见到那工厂模式来减缓业务的耦合度。
优化后的代码:
策略上下文
public class CashContext {
private CashSupper supper;
/**
* 根据指令获取相对应的计算方式
* @param command 执行 (正常收费/满300减100/八折活动)
*/
public CashContext(String command) {
this.supper = CashFactory.getCashAccept(command);
}
/**
* 计算
* @param money 原价
* @return 结果
*/
public double getResult(double money){
return supper.acceptCash(money);
}
}
执行
public class Run {
public static void main(String[] args) {
CashContext cashContext = new CashContext("正常收费");
CashContext cashContext1 = new CashContext("满300减100");
CashContext cashContext2 = new CashContext("八折活动");
System.out.println(cashContext.getResult(400));
System.out.println(cashContext1.getResult(400));
System.out.println(cashContext2.getResult(400));
}
}
策略模式的好处在于 对于客户端没有暴露任何的算法相关的类,和上面的简单工厂模式相对比的话 简单工厂有 CashFacotry 和 CashSuper 的业务的暴露,相对于简单工厂模式,策略模式只暴露了和业务无关的CashContext 给客户端,加入我们更新或者新增业务的话我们无需关心客户端。
为此张三一心打代码,然后赔光了所有的钱
全剧终