最近和一位曾在华为工作过的朋友聊天,谈到一些关于软件开发的事情,虽然他现在职位已经是高级工程师了,但平时主要工作内容还是负责业务关系,也更关注业务逻辑的实现。 遇到一些稍微复杂点的业务逻辑,少不了要用到if else ,但重复繁琐的if else,要是没有处理好,会给后期维护带来了诸多不便。 同样是写if else的,这位华为高级工程师平时的做法跟普通的开发者还有一定的区别的。 1.提前return 假如有下面的逻辑 if(condition){ //do something } else { return 0; } 这样编写的if else 中规中矩,从逻辑看完全没有问题,但这样的if else 完全可以通过对判断条件取反,代码在逻辑表达上会更加清晰。 if(!condition){ return 0; } //do something 这样从代码可读性看,我觉得第二种写法结构会更清晰,有利于后期代码维护。 第一种写法,中规中矩的,if else 都齐全,而第二种写法,从代码行数来看,我觉得更简洁。让你来看这两种写法,你更倾向哪一个呢? 2.使用Optional简化if判空处理 if(obj !=null){ return value1; } else { return value2; } 使用Optional后 Optional.ofNullable(obj).map(value1).orElse(value2); 要是没有else的场景,可以使用ifPresent 需要注意的是从 在使用jdk8时 我们使用jdk8的新特性Optional类解决判断为Null的问题 在 jdk9 时对 Optional 类进行了改进,增加了 ifPresentOrElse() 方法,使用ifPresentOrElse()要注意jdk 版本问题。 我个人觉得使用Optional来判断空对象,比if更简洁,同时也更好地避免空指针异常。 3.策略模式 上面两种只是关于if else 做简单的处理。如果你对设计模式有所了解,也可以通过采用策略模式来优化if else 的写法。 下面我们来看一个具体案例。假设有这么一个需求: 一个电商平台,当用户消费满1000金额时,这时候需要根据用户不同等级,给用户享受不同的优惠。 优惠规则如下: 普通VIP 不打折 黄金 优惠100元 钻石 8折 plus 优惠100元,再打7折 我们可以先用伪代码来实现下: private static BigDecimal getResult(BigDecimal money, int userType) { BigDecimal result = money; if (money >= 1000) { if (userType == UserType.GOLD) { System.out.println("黄金 优惠100元"); result = money - 100; } else if (userType == UserType.DIAMOND) { System.out.println("钻石 8折"); result = money * 0.8; } else if (userType == UserType.PLUS) { System.out.println("plus 优惠100元,再打7折"); result = (money - 100) * 0.7; } else { System.out.println("普通VIP 不打折"); result = money; } } return result; } 上面这段伪代码我们就把功能实现了,但要是从代码的整洁度来看,不太乐观,尤其是对于编写代码有严格的要求的,这样的代码恐怕过不了代码审核环节。 这时候我们就可以考虑使用前面提到的策略模式, 使用策略模式编写代码的伪代码 public interface Strategy { // 金额优惠计费函数 BigDecimal compute(BigDecimal money); } // 普通会员策略 public class VIPStrategy implements Strategy { @Override public BigDecimal compute(BigDecimal money) { System.out.println("普通VIP 不打折"); return money; } } // 黄金策略 public class GoldStrategy implements Strategy { @Override public BigDecimal compute(BigDecimal money) { BigDecimal num1 = new BigDecimal(100); System.out.println("黄金 优惠100元"); return money.subtract(num1); } } // 钻石策略 public class DiamondStrategy implements Strategy{ @Override public BigDecimal compute(BigDecimal money) { System.out.println("钻石 8折"); BigDecimal num2 = new BigDecimal(0.8); return money.multiply(num2); } } // Plus策略 public class PlusStrategy implements Strategy { @Override public BigDecimal compute(BigDecimal money) { System.out.println("plus 优惠100元,再打7折"); BigDecimal num1 = new BigDecimal(100); BigDecimal num2 = new BigDecimal(0.7); return money.subtract(num1).multiply(num2); } } 上面我们定义了一个 Strategy 接口,并且自定义四个子类,实现了接口。 并在对应的 compute函数中实现自身策略的优惠计费方式。 看着应该很不错的,但要是实际中我们还会用到了繁琐的if else。 public interface Strategy { BigDecimal compute(BigDecimal money); // 返回 type int getType(); } public class VIPStrategy implements Strategy { @Override public BigDecimal compute(BigDecimal money) { System.out.println("普通会员 不打折"); return money; } // 添加 type 返回 @Override public int getType() { return UserType.VIP; } } public class GoldStrategy implements Strategy { @Override public BigDecimal compute(BigDecimal money) { System.out.println("黄金 优惠100元"); BigDecimal num1 = new BigDecimal(100); return money.subtract(num1); } // type 返回 @Override public int getType() { return UserType.GOLD; } } public class StrategyFactory { private Mapmap; public StrategyFactory() { List strategies = new ArrayList<>(); strategies.add(new VIPStrategy()); strategies.add(new GlodStrategy()); strategies.add(new DiamondStrategy()); strategies.add(new PlusStrategy()); map = strategies.stream().collect(Collectors.toMap(Strategy::getType, strategy -> strategy)); } public static class Holder { public static StrategyFactory instance = new StrategyFactory(); } public static StrategyFactory getInstance() { return Holder.instance; } public Strategy get(Integer userType) { return map.get(userType); } } 这样一来就没有了if else了。 private static double getResult(doublemoney, int userType) { if (money < 1000) { return money; } Strategy strategy = StrategyFactory.getInstance().get(userType); if (strategy == null){ throw new IllegalArgumentException("用户类型有误"); } return strategy.compute(money); } 有时候一个简单的业务需求,不同开发人员实现的逻辑差不多,但有的编写的代码考虑就不是很齐全,容易在后面花更多的时间来修正,一个程序员的大部分时间,都是用在了分析需求和debug程序上了 代码编写不规范,不清晰,后面维护起来真的让你如履薄冰。 尤其是项目比较大,代码规范会更加重要。所以,在编写代码前多注意一些细节问题,后面项目维护起来会更加方便。 总结: 平时要实现功能时,要多留意下设计模型,工厂模式+策略模式+单例模式,这几种常用的模式在实际应用会经常使用到,掌握了可能会事半功倍的效果。 #2022职场年终盘点#