第四十二章 修复bug(2/2)
类似的,尽量把进程写的「大众化」一点,没有必要不碰新特性,也可以在很大程度上避免「遭遇官方bug」问题——如果你自己理解上再有点偏差,用新特性就和作死无异了。
不过……
有的人敲字灌水都错字连篇,但是有人手写几十上百万字的小说,随便截一段都差不多能进语文课本……
所以,人与人还是有极大差别的。
不能因为「Linus也写bug」甚至「Linus也写过低级bug」,就认为「我写个一百个整数里找最大值的简单进程出三十个bug也是正常的」——初学者搞出这事,正常。
至于专业人员嘛……出一个都不正常。
不仅如此。
既然「写长篇出bug正常,发条短信就那么十几个字,错一个都不应该」;那么我们把长篇拆开成若干章,一章只写三千字呢?再把一章拆开成若干段,一段只写数百个字呢?
这就是为何写进程要先做模块设计、然后再把模块按职责拆分成类、类按功能拆分成函数、最后还要求一个函数不要超过一屏(大约80行)的原因了。
经过拆分之后,一个一个函数填写实现、然后再一个一个函数做单元测试,测完再组合起来搞功能测试、集成测试……
这样写进程,当然还是无法杜绝bug出现;但出bug的几率就微乎其微了。
而且进程和长篇小说不同。
小说里的角色,尤其是主角和主要配角往往是贯穿始终的,这就使得小说章与章之间存在很多内部联系;稍微搞不好就会导致前后失去呼应,比如主角一会儿伤在左手一会儿伤在右臂、或者前面挖个坑然后设个伏笔后面却忘了用,等等。
但是在进程里面,不同模块甚至不同函数之间,应该是毫无瓜葛的,每一个都可以摘出来独立成库——有瓜葛就说明用了全局变量或者静态对象,或者通过参数或者约定等传递了过多的东西——这就叫「低耦合」。
做到了「低耦合」,你就可以把一个复杂的大进程当一组简单的短文甚至短信写。
这样自然就很难出错了。
当然了,有些情况下,进程逻辑非常复杂且无法拆分,也就是所谓「无法约分的复杂性」,这种代码就必须端起十二分小心来,当然即便如此,bug出现率仍然要远高于其他代码。
一般来说,要把进程拆成「不可约分」的一组最小单元来写。
这个「不可约分」就是术语说的「高内聚」:这段进程只做一件事,这件事已经没法拆的更简单了,只能把它们放在同一段代码里一举解决掉。
因此,写进程时,事先的「谋划」非常重要。
一个有经验的资深工程师,可以在动手前就把一个复杂的大项目拆成一堆几乎互不关联的小进程,然后逐一实现它们、实现完再把它们组合起来就行了。
显然,「谋划」好了,一个进程的难度降低若干个数量级都是可能的。
说实话,在绝大部分能见到的软件中,都是或多或少的有bug的……
只不过,第一开发可能没想到,第二测试没测到,第三用户没碰到,第四客服的反馈没收到,那么——这就是一个「成熟稳健」的产品。