Use Guard Clauses to Avoid Nested Logic for Better Readability

使用 Guard Clauses 回避嵌套的流程判断来增进阅读性

遇见问题

什么是嵌套的流程判断?嵌套又会带来什么问题?举例一个实际的例子来说:「验证用户输入的信息」。 要达成这个目的就必须对输入检查,例如:检查信息是否为空、检查信息是否符合规范、检查任何可能的错误情境……等。

function signupUser(username, password, passwordConfirmation) {
if (username === '') {
return '用户名是必填的';
} else {
if (password === '') {
return '密码是必填的';
} else {
if (password !== passwordConfirmation) {
return '密码确认不符';
} else {
return '执行注册';
}
}
}
}

目前问题在于,它的嵌套层级太深了,这样的代码会让人很难阅读,而且也很难维护与更动! 让我们试试看使用 Guard Clauses (守卫判断)来改写这段程序:

function signupUser(username, password, passwordConfirmation) {
if (username === '') {
return '用户名是必填的';
}
if (password === '') {
return '密码是必填的';
}
if (password !== passwordConfirmation) {
return '密码确认不符';
}
return '执行注册';
}

只要改动思考判断的模式(尽早返回,终止整个函数),就可以达到更好的可读性,也可以减少嵌套的层级。

总结

如果你需要大于 3 层的嵌套,说明你已经搞砸了,应考虑重构代码。

会出现这么多嵌套的原因是因为我们的思考模式是“先检查错误,再执行正常的流程”,但这样会让代码变得很难阅读,因此我们可以改变思考模式,先返回掉反面的条件,这就是 Guard Clauses 的概念。最后总结两种终结嵌套的方式:

反转

提早返回异常的状态可以让我们更加专注在 Happy Path🔗 (无异常流程)上,并且能随着需求的增加轻易地改动与理解逻辑。

封装

如果程序真的太复杂,应考虑抽离片段出来独立成一个单一功能的函数,这样可以让代码更加清晰且专一。

参考资料