从华为跳槽来的工程师,繁琐的if else都处理得这么优雅

最近和一位曾在华为工作过的朋友聊天,谈到一些关于软件开发的事情,虽然他现在职位已经是高级工程师了,但平时主要工作内容还是负责业务关系,也更关注业务逻辑的实现。

遇到一些稍微复杂点的业务逻辑,少不了要用到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 Map map;
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职场年终盘点#

展开阅读全文

页面更新:2024-03-06

标签:华为   写法   繁琐   钻石   逻辑   优雅   策略   工程师   模式   代码   黄金   业务   用户

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top