利用策略模式和工厂模式优化代码中过多的if-else
2020-01-12 23:17
337 查看
在公司经常会遇到一些需要做一连串相似的业务逻辑判断需求,比如使用不同支付方式实现商品打折、商店根据客户的vip等级给予客户不同的优惠政策之类的业务场景。假设现在我们接到一个需求,根据客户的VIP等级,给与不同的优惠政策:
// VIP1 消费1000 ~ 2000,9折优惠, 消费2000~5000,8折优惠,消费5000~10000,7折优惠, 消费10000~,6折优惠 static String VIP1 = "VIP1"; // VIP2 消费1000 ~ 2000,8.5折优惠, 消费2000~5000,7.5折优惠,消费5000~10000,6.5折优惠,消费10000~,5.5折优惠 static String VIP2 = "VIP2"; // VIP3 消费1000 ~ 2000,8折优惠, 消费2000~5000,7折优惠,消费5000~10000,6折优惠, 消费10000~,5折优惠 static String VIP3 = "VIP3"; // VIP4 消费1000 ~ 2000,7.5折优惠, 消费2000~5000,6.5折优惠,消费5000~10000,5.5折优惠, 消费10000~,4.5折优惠 static String VIP4 = "VIP4"; // VIP5 消费1000 ~ 2000,7折优惠, 消费2000~5000,6折优惠,消费5000~10000,5折优惠, 消费10000~,4折优惠 static String VIP5 = "VIP5"; // VIP6 消费1000 ~ 2000,6.5折优惠, 消费2000~5000,5.5折优惠,消费5000~10000,4.5折优惠, 消费10000~,3.5折优惠 static String VIP6 = "VIP6";
现在商店来了一个客户,我们需要根据客户的会员等级实现不同的优惠策略。通常使用if-else代码如下:
static BigDecimal PRICE1000 = new BigDecimal(1000); static BigDecimal PRICE2000 = new BigDecimal(2000); static BigDecimal PRICE5000 = new BigDecimal(5000); static BigDecimal PRICE10000 = new BigDecimal(10000); public BigDecimal getPrice(Client client, BigDecimal price){ BigDecimal realPrice = price; if(VIP1.equals(client.getType())){ if(PRICE1000.compareTo(price) < 0 && PRICE2000.compareTo(price) >= 0){ realPrice = new BigDecimal("0.9").multiply(price); } else if(PRICE2000.compareTo(price) < 0 && PRICE5000.compareTo(price) >= 0){ realPrice = new BigDecimal("0.8").multiply(price); } else if(PRICE5000.compareTo(price) < 0 && PRICE10000.compareTo(price) >= 0){ realPrice = new BigDecimal("0.7").multiply(price); } else if(PRICE10000.compareTo(price) < 0){ realPrice = new BigDecimal("0.6").multiply(price); } } else if(VIP2.equals(client.getType())){ //... } else if(VIP3.equals(client.getType())){ //... } else if(VIP4.equals(client.getType())){ //... } else if(VIP5.equals(client.getType())){ //... } else if(VIP6.equals(client.getType())){ //... } return realPrice; }
很抱歉,实在写不下去了,重复这样子写有些累,后面VIP2~VIP6只需要仿照VIP1的优惠策略写就行,我在这里只是想要表达这种写法实在不怎么样,读者明白我的意思就行。这里可以通过使用策略模式进行优化:
// 策略接口 public interface VIP { static BigDecimal PRICE1000 = new BigDecimal(1000); static BigDecimal PRICE2000 = new BigDecimal(2000); static BigDecimal PRICE5000 = new BigDecimal(5000); static BigDecimal PRICE10000 = new BigDecimal(10000); BigDecimal getPrice(BigDecimal price); } // 具体策略实现类 public class VIP1 implements VIP { @Override public BigDecimal getPrice(BigDecimal price) { BigDecimal realPrice = price; if(PRICE1000.compareTo(price) < 0 && PRICE2000.compareTo(price) >= 0){ realPrice = new BigDecimal("0.9").multiply(price); } else if(PRICE2000.compareTo(price) < 0 && PRICE5000.compareTo(price) >= 0){ realPrice = new BigDecimal("0.8").multiply(price); } else if(PRICE5000.compareTo(price) < 0 && PRICE10000.compareTo(price) >= 0){ realPrice = new BigDecimal("0.7").multiply(price); } else if(PRICE10000.compareTo(price) < 0){ realPrice = new BigDecimal("0.6").multiply(price); } return realPrice; } } // 这里只将VIP1的具体实现放了上来,其他几种策略意思差不多 public class Shop { public BigDecimal getPrice(Client client, BigDecimal price){ VIP vip = null; if(VIP1.equals(client.getType())){ vip = new VIP1(); } else if(VIP2.equals(client.getType())){ vip = new VIP2(); } else if(VIP3.equals(client.getType())){ vip = new VIP3(); } else if(VIP4.equals(client.getType())){ vip = new VIP4(); } else if(VIP5.equals(client.getType())){ vip = new VIP5(); } else if(VIP6.equals(client.getType())){ vip = new VIP6(); } return vip.getPrice(price); } public static void main(String[] args) { Shop shop = new Shop(); Client client = new Client(); client.setType(Shop.VIP1); client.shopping(shop, new BigDecimal(10000)); } }
显然,这样子代码看着舒服了一些,而且后面如果哪个VIP等级的优惠政策有了更改,我们只需要在相应的策略实现类中进行修改即可,另外之后如果添加VIP7…VIPN是只需要添加具体策略实现类就行。当然,这样也会导致后面的类文件十分多,会增添项目文件管理上的麻烦,这一点是需要我们注意的。另外,眼尖的你应该也发现了,上面的代码还是有很多if-else,具体策略类中的if-else暂时无能为力(可以使用策略模式,但是感觉使用了策略模式之后项目文件管理会变成一个巨大的麻烦),后面如果我有了方法解决这个问题,会再更新这篇文章。具体使用哪种策略时使用的if-else判断是可以利用Map来替换,Map中的key为用户VIP类型,value为具体策略类型。利用Map我们可以直接通过get方法拿到我们想要的具体策略实现类的实例,从而获取相应的方法。具体实现大体如下:
public class VIPFactory { private static VIPFactory factory = new VIPFactory(); private VIPFactory(){} private static Map vipMap = new HashMap<>(); static { vipMap.put(Shop.VIP1, new VIP1()); vipMap.put(Shop.VIP2, new VIP2()); vipMap.put(Shop.VIP3, new VIP3()); vipMap.put(Shop.VIP4, new VIP4()); vipMap.put(Shop.VIP5, new VIP5()); vipMap.put(Shop.VIP6, new VIP6()); } public static VIPFactory getInstance(){ return factory; } public VIP getVip(String vipType){ return (VIP) vipMap.get(vipType); } } public class Shop { public BigDecimal getPrice(Client client, BigDecimal price){ VIP vip = VIPFactory.getInstance().getVip(client.getType()); return vip.getPrice(price); } public static void main(String[] args) { Shop shop = new Shop(); Client client = new Client(); client.setType(Shop.VIP1); client.shopping(shop, new BigDecimal(10000)); } }
具体的策略实现类我就不再赘述了,工厂使用的是单例模式。其实这个时候可以很明显到感觉代码看起来舒服多了。
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- Java利用策略模式优化过多if else代码
- 利用策略模式优化过多 if else 代码
- Android设计模式 -- 巧用策略模式告别过多的 if...else...
- 利用Freemarker生成doc文件(包含list循环,ifelse判断,合并单元格,嵌入表格单元格字数过多报错等)
- 过多if-else分支的优化
- 设计模式-策略模式Strategy以及消灭if else
- java中过多if-else分支语句的优化方案
- 过多if-else分支的优化
- 策略模式+工厂模式优化if...else if...else if结构
- 代码中如何避免过多的if else
- CPU与代码优化(1):用三元操作符替代if-else以降低CPU分支预测惩罚;函数13倍提速(Unity)。
- 代码优化——去除你代码中的if...else...层层嵌套
- 设计模式——行为型模式之借助策略模式(Strategy Pattern)减少使用不必要的if-else if -else和switch-case(三)
- 过多if-else分支的优化
- 优化代码中大量的if/else,你有什么方案?
- if-else过多的分支优化
- 代码优化——去除你代码中的if...else...层层嵌套
- JDBC之使用策略模式和模板方法模式优化代码
- 结合策略模式和HashMap摆脱if else
- 使用策略模式减少if else