第四十二章 修復bug(2/2)
類似的,儘量把程序寫的「大眾化」一點,沒有必要不碰新特性,也可以在很大程度上避免「遭遇官方bug」問題——如果你自己理解上再有點偏差,用新特性就和作死無異了。
不過……
有的人敲字灌水都錯字連篇,但是有人手寫幾十上百萬字的小說,隨便截一段都差不多能進語文課本……
所以,人與人還是有極大差別的。
不能因為「Linus也寫bug」甚至「Linus也寫過低級bug」,就認為「我寫個一百個整數里找最大值的簡單程序出三十個bug也是正常的」——初學者搞出這事,正常。
至於專業人員嘛……出一個都不正常。
不僅如此。
既然「寫長篇出bug正常,發條簡訊就那麼十幾個字,錯一個都不應該」;那麼我們把長篇拆開成若干章,一章只寫三千字呢?再把一章拆開成若干段,一段只寫數百個字呢?
這就是為何寫程序要先做模塊設計、然後再把模塊按職責拆分成類、類按功能拆分成函數、最後還要求一個函數不要超過一屏(大約80行)的原因了。
經過拆分之後,一個一個函數填寫實現、然後再一個一個函數做單元測試,測完再組合起來搞功能測試、集成測試……
這樣寫程序,當然還是無法杜絕bug出現;但出bug的機率就微乎其微了。
而且程序和長篇小說不同。
小說里的角色,尤其是主角和主要配角往往是貫穿始終的,這就使得小說章與章之間存在很多內部聯繫;稍微搞不好就會導致前後失去呼應,比如主角一會兒傷在左手一會兒傷在右臂、或者前面挖個坑然後設個伏筆後面卻忘了用,等等。
但是在程序裡面,不同模塊甚至不同函數之間,應該是毫無瓜葛的,每一個都可以摘出來獨立成庫——有瓜葛就說明用了全局變量或者靜態對象,或者通過參數或者約定等傳遞了過多的東西——這就叫「低耦合」。
做到了「低耦合」,你就可以把一個複雜的大程序當一組簡單的短文甚至簡訊寫。
這樣自然就很難出錯了。
當然了,有些情況下,程序邏輯非常複雜且無法拆分,也就是所謂「無法約分的複雜性」,這種代碼就必須端起十二分小心來,當然即便如此,bug出現率仍然要遠高於其他代碼。
一般來說,要把程序拆成「不可約分」的一組最小單元來寫。
這個「不可約分」就是術語說的「高內聚」:這段程序只做一件事,這件事已經沒法拆的更簡單了,只能把它們放在同一段代碼里一舉解決掉。
因此,寫程序時,事先的「謀劃」非常重要。
一個有經驗的資深工程師,可以在動手前就把一個複雜的大項目拆成一堆幾乎互不關聯的小程序,然後逐一實現它們、實現完再把它們組合起來就行了。
顯然,「謀劃」好了,一個程序的難度降低若干個數量級都是可能的。
說實話,在絕大部分能見到的軟體中,都是或多或少的有bug的……
只不過,第一開發可能沒想到,第二測試沒測到,第三用戶沒碰到,第四客服的反饋沒收到,那麼——這就是一個「成熟穩健」的產品。