85 lines
6.1 KiB
Markdown
85 lines
6.1 KiB
Markdown
# 32 | 答疑(三):如何选择合适的异常处理方式?
|
||
|
||
你好,我是景霄。
|
||
|
||
不知不觉中,我们又一起完成了第三大章规范篇的学习。我非常高兴看到很多同学一直在坚持积极地学习,并且留下了很多高质量的留言,值得我们互相思考交流。也有一些同学反复推敲,指出了文章中一些表达不严谨或是不当的地方,我也表示十分感谢。
|
||
|
||
大部分留言,我都在相对应的文章中回复过了。而一些手机上不方便回复,或是很有价值很典型的问题,我专门摘录了出来,作为今天的答疑内容,集中回复。
|
||
|
||
## 问题一:应该使用哪种异常处理方式?
|
||
|
||
![](https://static001.geekbang.org/resource/image/c7/42/c766890764672c7c924092d9dfd0c942.png)
|
||
|
||
第一个问题是code2同学的疑惑。下面这两种处理的风格,哪一种风格更有效、更优雅?
|
||
|
||
* 第一种,在代码中对数据进行检测,并直接处理与抛出异常。
|
||
* 第二种,在异常处理代码中进行处理。
|
||
|
||
其实,第一种方法,可以翻译成下面的“if…elif…”语句:
|
||
|
||
```
|
||
if [condition1]:
|
||
raise Exception1('exception 1')
|
||
elif [condition2]:
|
||
raise Exception2('exception 2')
|
||
...
|
||
|
||
```
|
||
|
||
而第二种方法,则对应着下面异常处理的代码:
|
||
|
||
```
|
||
try:
|
||
...
|
||
except Exception as e:
|
||
...
|
||
|
||
```
|
||
|
||
这两种方法很大的一个区别是,第一种方法一旦抛出异常,那么程序就会终止;而在第二种方法中,如果抛出异常,会被程序捕获(catch),程序还会继续运行。这也是我们选择这两种方法的重要依据。当然,在实际工作中,到底使用哪一种方法,还是取决于具体的场景。
|
||
|
||
比方说,一个模块的功能是对输入进行检测,如果输入不合法,则弹出对话框进行提示,并终止程序。那么,这种情况下,使用第一种方法更加合理。
|
||
|
||
但是,如果换成一个产品的服务器端,它需要应对各种可能发生的情况,以保证服务器不崩溃。比如在连接数据库时,如果网络异常,无法连接,那就需要捕获(catch)这个异常(exception),进行记录,并同时保证其他功能不受影响。这种情况下,我们通常会选择第二种方式。
|
||
|
||
## 问题二:先写出能跑起来的代码,后期再优化可以吗?
|
||
|
||
![](https://static001.geekbang.org/resource/image/d5/b0/d5efddbe80757e61e33596ce41440bb0.png)
|
||
|
||
第二个问题,夜路破晓同学提到了很多程序员传授的“经验之谈”,即先写出能跑起来的代码,后期再优化。很明显,这种认知是错误的。我们从一开始写代码时,就必须对功能和规范这两者双管齐下。
|
||
|
||
代码功能完整和规范完整的优先级是不分先后的,应该是同时进行的。如果你一开始只注重代码的功能完整,而不关注其质量、规范,那么规范问题很容易越积越多。这样就会导致产品的bug越来越多,相应的代码库越发难以维护,到最后不得已只能推倒重来。
|
||
|
||
我在Facebook工作时就遇到过这样的情况,参与过类似的项目。当时,某些功能模块因为赶时间,code review很宽松,代码写得很不规范,留下了隐患。时间一长,bug越来越多,legacy越来越多。到最后,万分无奈的情况下,我们几个工程师专门立项,花了三个多月时间,重写了这一模块的代码,才解决了这个问题。
|
||
|
||
## 问题三:代码中写多少注释才合适?
|
||
|
||
![](https://static001.geekbang.org/resource/image/f2/71/f22b2ec07051b244ed4a852189745671.png)
|
||
|
||
第三个问题,小侠龙旋风同学留言说,自己的同事要求代码中有70%的注释,这显然有点过了。但是反过来说,如果你的代码中没有注释或者注释很少,仅凭规范的变量名肯定是远远不够的。
|
||
|
||
通常来说,我们会在类的开头、函数的开头或者是某一个功能块的开头加上一段描述性的注释,来说明这段代码的功能,并指明所有的输入和输出。除此之外,我们也要求在一些比较tricky的代码上方加上注释,帮助阅读者理解代码的含义。
|
||
|
||
总的来说,代码中到底需要有多少注释,其实并没有一个统一的要求,还是要根据代码量和代码的复杂度来决定。不过,我们平常书写时,只要满足这样的规范就可以了。
|
||
|
||
另外,必须提醒一点,如果在写好之后修改了代码,那么代码对应的注释一定也要做出相应的修改,不然很容易造成“文不对题”的现象,给别人也给你自己带来困扰。
|
||
|
||
## 问题四:项目的API文档重要吗?
|
||
|
||
![](https://static001.geekbang.org/resource/image/fc/c5/fc59ac08ab33764afa439056e75acac5.png)
|
||
|
||
第四个问题,是未来已来同学的留言。他提到了项目的API文档的问题,这一点说得非常好,在这里我也简单介绍一下。
|
||
|
||
我在专栏中主要讲的是代码的规范问题,但很多情况下,光有规范的代码还是远远不够的。因为一个系统,一个产品,甚至一个功能模块的代码,都有可能非常复杂。少则几千行,动辄几十万行,尤其是对于刚加入的新人来说,在ramp up阶段光看代码可能就是一个噩梦了。
|
||
|
||
因此,在这方面做得比较规范的公司,通常也会要求书写文档。项目的文档,主要是对相应的系统、产品或是功能模块做一个概述,有助于后人理解。以一个service为例,其对应的文档通常会包括下面几部分:
|
||
|
||
* 第一点,系统的概述,包括各个组成部分以及工作流程的介绍;
|
||
* 第二点,每个组成部分的具体介绍,包括必要性、设计原理等等;
|
||
* 第三点,系统的performance,包括latency等等参数;
|
||
* 第四点主要说明如何对系统的各个部分进行修改,主要给出相应的code pointer及对应的测试方案。
|
||
|
||
这些内容,也希望屏幕前的你能够牢记。
|
||
|
||
今天我主要回答这些问题,同时也欢迎你继续在留言区写下疑问和感想,我会持续不断地解答。希望每一次的留言和答疑,都能给你带来新的收获和价值。
|
||
|