策略模式

某日张三中了注30倍的双色球一等奖,张三为此结束了自己的程序员的职业生涯,挥霍几日后突发奇想,想开个商场,过某日商场开业,张三心血来潮想写代码,正巧碰上了自己家的商场有各种活动,随即兴起写个商场促销的业务代码。

业务

自家商场打折 部分规则如下:

有的商品不打折 原价,部分商品 满500减200 另有之八五折。

代码撸开~ 在写时想到前几天 的一个文章简单工厂模式感觉可行随后吭哧吭哧撸开。。。

代码:

公共抽象类

  1. public abstract class CashSupper {
  2. /**
  3. * 计算结果
  4. * @param money 原价
  5. * @return 结果
  6. */
  7. public abstract double acceptCash(double money);
  8. }

正常收费业务

打折收费业务

  1. public class CashRebate extends CashSupper {
  2. private double moneyRebate = 1D;
  3. /**
  4. * 构造
  5. * @param moneyRebate 打折率
  6. */
  7. public CashRebate(double moneyRebate) {
  8. this.moneyRebate = moneyRebate;
  9. }
  10. @Override
  11. public double acceptCash(double money) {
  12. return money * moneyRebate;
  13. }
  14. }

满减收费业务

  1. public class CashReturn extends CashSupper {
  2. /**
  3. * 满足条件金额
  4. */
  5. private double monetCondition;
  6. /**
  7. * 满足条件后返利金额
  8. */
  9. private double moneyReturn;
  10. /**
  11. * 构造
  12. * @param monetCondition 满足条件金额
  13. * @param moneyReturn 满足条件后返利金额
  14. */
  15. public CashReturn(double monetCondition, double moneyReturn) {
  16. this.monetCondition = monetCondition;
  17. this.moneyReturn = moneyReturn;
  18. }
  19. @Override
  20. public double acceptCash(double money) {
  21. double result = money;
  22. if (money >= monetCondition) {
  23. result = money - moneyReturn;
  24. }
  25. return result;
  26. }
  27. }

简单工厂

  1. public class CashFactory {
  2. public static CashSupper getCashAccept(String type){
  3. CashSupper supper = null;
  4. switch (type) {
  5. case "正常收费" :
  6. supper = new CashNormal();
  7. break;
  8. case "满300减100" :
  9. supper = new CashReturn(300, 100);
  10. break;
  11. case "八折活动" :
  12. supper = new CashRebate(0.8);
  13. break;
  14. default:
  15. }
  16. return supper;
  17. }
  18. }

执行

  1. public class Run {
  2. public static void main(String[] args) {
  3. CashSupper cashSupper = CashFactory.getCashAccept("正常收费");
  4. System.out.println("正常收费:"+cashSupper.acceptCash(400));
  5. CashSupper cashSupper1 = CashFactory.getCashAccept("满300减100");
  6. System.out.println("满300减100:"+cashSupper1.acceptCash(400));
  7. CashSupper cashSupper2 = CashFactory.getCashAccept("八折活动");
  8. System.out.println("八折活动:"+cashSupper2.acceptCash(400));
  9. }
  10. }

作为老板的张三撸完代码后发现一个很头痛的问题,现在的业务相对来说并不是特别的复杂,如果遇到十月一双十一这种业务复杂的时间段的话,业务肯定的繁重,于是搜集资料经过研究发现可以对其进行结构化的优化使用 策略模式搭配见到那工厂模式来减缓业务的耦合度。

优化后的代码:

策略上下文

  1. public class CashContext {
  2. private CashSupper supper;
  3. /**
  4. * 根据指令获取相对应的计算方式
  5. * @param command 执行 (正常收费/满300减100/八折活动)
  6. */
  7. public CashContext(String command) {
  8. this.supper = CashFactory.getCashAccept(command);
  9. }
  10. /**
  11. * 计算
  12. * @param money 原价
  13. * @return 结果
  14. */
  15. public double getResult(double money){
  16. return supper.acceptCash(money);
  17. }
  18. }

执行

  1. public class Run {
  2. public static void main(String[] args) {
  3. CashContext cashContext = new CashContext("正常收费");
  4. CashContext cashContext1 = new CashContext("满300减100");
  5. CashContext cashContext2 = new CashContext("八折活动");
  6. System.out.println(cashContext.getResult(400));
  7. System.out.println(cashContext1.getResult(400));
  8. System.out.println(cashContext2.getResult(400));
  9. }
  10. }

策略模式的好处在于 对于客户端没有暴露任何的算法相关的类,和上面的简单工厂模式相对比的话 简单工厂有 CashFacotry 和 CashSuper 的业务的暴露,相对于简单工厂模式,策略模式只暴露了和业务无关的CashContext 给客户端,加入我们更新或者新增业务的话我们无需关心客户端。

为此张三一心打代码,然后赔光了所有的钱

全剧终