昨天写了关于写代码的一点心得之后,大家对于第七条有一些争议,技术群里也有关于这个问题的探讨,今天就来聊下这个问题。
我们今天来看下这个问题,比如我现在写一段代码,示例是对用户的支付请求做处理:
如果是按照错误码的方式处理,我们来看下代码应该写:
public CommonResult handlePayment(PayRequest request) {
//1. 校验
ErrorCodeEnum errorCodeEnum = validateUserInfo();
if (Objects.notNull(errorCodeEnum)) {
printWarnLog("***", errorCodeEnum);
return Result.buildErrorResult(errorCodeEnum);
}
//2. 获取指定支付类型处理器
PayTypeEnum payTypeEnum = PayTypeEnum.getPayType(request.getPayCode());
PayHandle payHandle = PayFactory.getHandle(payTypeEnum);
if (null == payHandle) {
printWarnLog("***", errorCodeEnum);
return Result.buildErrorResult(ErrorCodeEnum.NO_VALID_PAY_TYPE);
}
//3. 执行支付
PayContext payContext = assemblePayContext(request);
PayResult payResult = payHandle.doHandle(payContext);
if (payResult == null) {
return Result.buildErrorResult(ErrorCodeEnum.***);
}
if (!payResult.isSuccess()) {
return Result.buildErrorResult(ErrorCodeEnum.***);
}
//4. 转化结果
CommonResult commonResult = ResultBuilder.convertFrom(payResult);
return commonResult;
}复制
大家可以看到代码的业务逻辑中充斥着校验、结果判断,一旦不符合预期通过错误码形式返回,这种形式的代码会让代码的阅读不通畅,看代码的人看一段中间态的业务逻辑,接着看这段业务逻辑的校验判断,实际上好的方式是直接在具体方法中直接抛出异常,我们看下。
public CommonResult service(HttpServletRequest request, HttpServletResponse response) {
CommonResult result = CommonResult.initResult();
try {
PayRequest payRequest = convertToPayResult(request);
result = handlePayment(payRequest);
} catch(Throwable ex) {
//集中异常处理
LogUtils.printErrorLog(method, msg, ex);
result = CommonResult.errorResult(ex);
} finally {
LogUtils.printInfoLog(method, status, time, info);
}
return result;
}
//只有主要的业务逻辑
public CommonResult handlePayment(PayRequest request) {
//1. 校验
validateUserInfo();
//2. 获取指定支付类型处理器
PayTypeEnum payTypeEnum = PayTypeEnum.getPayType(request.getPayCode());
PayHandle payHandle = PayFactory.getHandle(payTypeEnum);
//3. 执行支付
PayContext payContext = assemblePayContext(request);
PayResult payResult = payHandle.doHandle(payContext);
//4. 转化结果
return ResultBuilder.convertFrom(payResult);
}
//校验逻辑直接丢异常
private void validateUserInfo() {
UserInfo userInfo = ThreadLocalUtils.getUserInfoFromSession();
if (illegalOf(userInfo)) {
throw new IllegalArgumentException("userInfo");
}
}
private boolean illegalOf(UserInfo userInfo) {
// doCheck
}
class PayFactory {
PayHandle getHandle(PayTypeEnum payTypeEnum) {
if (null = payTypeEnum) {
throw new NullPointerException("payTypeEnum");
}
PayHandle payHandle = payHandleMap.get(payTypeEnum.getCode());
if (null = payHandle) {
throw new XXXBizException();
}
return payHandle;
}
}复制
本质上来说异常只是把复杂性留在更低抽象层次,因为我们日常阅读代码最多的还是在高抽象层。
有读者可能会说异常比返回错误码更消耗性能,但是实际上我们的应用程序大部分时候是性能过剩的,而可阅读性和可维护性欠缺的,如果程序需要在这个地方做性能优化,那证明真的应该找老板扩容了。
昨天的文章:
文章转载自安琪拉的博客,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
数据库国产化替代深化:DBA的机遇与挑战
代晓磊
1224次阅读
2025-04-27 16:53:22
2025年4月国产数据库中标情况一览:4个千万元级项目,GaussDB与OceanBase大放异彩!
通讯员
690次阅读
2025-04-30 15:24:06
国产数据库需要扩大场景覆盖面才能在竞争中更有优势
白鳝的洞穴
576次阅读
2025-04-14 09:40:20
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
496次阅读
2025-04-17 17:02:24
一页概览:Oracle GoldenGate
甲骨文云技术
472次阅读
2025-04-30 12:17:56
GoldenDB数据库v7.2焕新发布,助力全行业数据库平滑替代
GoldenDB分布式数据库
466次阅读
2025-04-30 12:17:50
优炫数据库成功入围新疆维吾尔自治区行政事业单位数据库2025年框架协议采购!
优炫软件
356次阅读
2025-04-18 10:01:22
国产数据库图谱又上新|82篇精选内容全览达梦数据库
墨天轮编辑部
269次阅读
2025-04-23 12:04:21
MySQL 30 周年庆!MySQL 8.4 认证免费考!这次是认真的。。。
数据库运维之道
249次阅读
2025-04-28 11:01:25
给准备学习国产数据库的朋友几点建议
白鳝的洞穴
237次阅读
2025-05-07 10:06:14