最小化嵌套
嵌套很深的代码很难以理解。每个嵌套层次都在读者的“思维栈”上又增加了一个条件。当读者见到一个右大括号(})时,可能很难“出栈”来回忆起它背后的条件是什么。
下面是一个相对简单的例子——当你回头复查你在读的是哪一个条件语句块时,你是否能注意到你自己:
当你看到第一个右大括号时,你不得不去想:“哦,permission_result!=SUCCESS刚刚结束,那么现在是在permission_result==SUCCESS之中了,并且还是在user_result==SUCCESS的语句块中。”
总之,你不得不始终记得user_result和permission_result的值。并且当每个if{}块结束后你都不得不切换你脑海中的值。
上例中的代码尤其不好,因为它不断地切换SUCCESS和non-SUCCESS的条件。
嵌套是如何累积而成的
在我们修正前面的示例代码之前,先来看看是什么导致它成了现在的样子。一开始,代码是很简单的:
这段代码很容易理解——它找出该写什么错误信息,然后回复并结束。
但是后来那个程序员增加了第二个操作:
这个改动有合理的地方——该程序员要插入一段新代码,并且她找到了最容易插入的地方。对于她来讲,新代码很整洁,而且很明确。这个改动的差异也很清晰——这看上去像是个简单的改动。
但是以后当其他人遇到这段代码时,所有的上下文早已不在了。这就是你在本节一开始读到这段代码时的情况,你不得不一下子全盘接受它。
关键思想
当你对代码做改动时,从全新的角度审视它,把它作为一个整体来看待。
通过提早返回来减少嵌套
好的,那么让我们来改进这段代码。像这种嵌套可以通过马上处理“失败情况”并从函数早返回来减少:
上面这段代码只有一层嵌套,而不是两层。但更重要的是,读者不再需要从思维堆栈里“出栈”了——每个if块都以一个return结束。
减少循环内的嵌套
提早返回这个技术并不总是合适的。例如,下面代码在循环中有嵌套:
在循环中,与提早返回类似的技术是continue:
与if(……)return;在函数中所扮演的保护语句一样,这些if(……)continue;语句是循环中的保护语句。
一般来讲,continue语句让人很困惑,因为它让读者不能连续地阅读,就像循环中有goto语句一样。但是在这种情况中,循环中的每个迭代是相互独立的(这是一种"for each"循环),因此读者可以很容易地领悟到这里continue的意思就是“跳过该项”。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论