看了很多剛參與開發工作時間不久的同事的代碼之後,心情總是很沉重,大家由於缺乏工程化的經驗,不知道如何寫好代碼,更加不知道如何站在軟體工程的角度來開發,從而大幅降低開發成本,特別是產品類開發,可以降低多輪迭代以及黑箱測試、後期維護的成本,而且可以直觀地降低大家的加班時間,正確的工程方法+需求的準確把握=成功的軟體工程。
這裡還是想藉此機會再重新談談軟體與程式的區別,所謂程式僅僅是在電腦上可以被編譯啟動並執行一段代碼而已,程式的設計可以是學術化的,譬如為了驗證某些演算法,某些學術目標,而軟體卻是將使用者的需求進行完整理解之後,依次按照設計、開發、單元測試、整合測試後帶有一定的架構定義以及品質保證的可執行檔代碼、文檔集合,一語中的地說,軟體是經過工程化管理出產後的程式與文檔集合,二者的差距就是在如下兩個方面:
- 軟體的需求目標非常鮮明;
- 軟體的品質是經過工程化控制的,品質達標的;
很多剛參與工作不久的同事都普遍地認軟體開發=程式開發,這個認識是非常有害的,最直觀的反應是在時間估算上,往往很多時候估算2周的工作,最後2個月都沒做完,明顯是對於軟體工程的認識上存在非常大的誤區。
本篇將重點講述一下代碼開發方面的程式REVIEW觀點集合,有關軟體工程的論述在後續的文章中再跟大家分享。
代碼REVIEW觀點集合:
“形”
1.曲線外形美:代碼曲線的外形要比較漂亮,好的代碼外形表現為比較柔和的鈍三角形,而糟糕的代碼由於書寫方式的不好而表現為外形跨度很大的銳三角形;
好的代碼外形:(過度比較平緩)
----
---------
-------------
----------
-------
不好的代碼外形:(雜亂無型)
-
-------------------------------------------------------------
-------
--
------------------------------------------------
2.函數型參,優秀的代碼風格在函數的型參上擁有嚴格的控制觀點,一般建議函數的參數控制在6個以內,超過6個的參數一般建議考慮通過結構體、指標或者引用對象等多種方式進行傳遞,而且一般來講,當單個函數的參數涉及的參數數量超過6個時,你需要考慮是否你的當前函數的處理邏輯設計是否出現了重大問題,這一點也是檢驗你設計思路的一個指標之一。
3.代碼長度限制,一般而言,單個函數的代碼長度建議控制在50行以內,最長建議不超過100行,設定這個指標的主要意義其實是為了人類的思維邏輯的分層處理,避免在思維設計時出現重大失誤帶來實現的諸多問題,對於這個指標,很多初始參與編程開發的同事總是觸犯這個規矩,到最後進行代碼調整修改排錯時我們經常發現這些同事在找某個問題時滿頭大汗,找到某個函數後修改的時候也是經常出現修改父函數的同時又去修改子函數,導致修複一個BUG引發其他的BUG,可能還會帶來嚴重的DEGRADE問題,這些都是因為違背了一些好的編程開發實踐所導致的。
4.行書寫長度限制,設定這個指標的主要目的其實是為了控制在目前主流的螢幕寬頻範圍內不用水平滾動即可實現代碼閱讀,過去舊的標準是建議控制在80個字元每行,新的推薦規範建議在120個字元每行。
5.命名規則,需要對變數名、函數名、類名、包名、檔案名稱等實施統一的命名管理規範,進一步增強代碼的可讀性,確保在團隊開發的時候代碼方便交流。很多開發經驗不足的開發人員總認為這個是個很大的約束,其實如果大家做過大項目的維護以及軟體逆向工程開發人員都認為這個確實非常重要,可讀性強的代碼要遠遠超過去閱讀那往往跟代碼看似相關而實際上總是跟不上代碼更新速度的厚厚的文檔集。
6.代碼注釋,優秀的代碼一定是含有非常好的代碼注釋,由於代碼注釋在很多的代碼編輯器裡面都呈現綠色,因此將注釋率稱為“綠化率”,推薦的綠化率為20-25%左右(行數比率),而且建議整體上分布均衡一點,確保代碼閱讀在注釋的協助下可以很容易完成,這點跟上面的命名規則一起可以決定增強代碼的可讀性。
設定“形”的觀點主要是為了便於代碼閱讀,便於其他開發人員為你的代碼做設計REVIEW,便於代碼溝通與交流,優秀的代碼除了執行效率高,可讀性強,可測試性好也是一個非常重要的指標,這些都最終直接決定著整體代碼的交付品質。
“神”
1.設計觀點:重點是高內聚、低耦合,其整體指導思路是模組內部的實現是高度內聚,模組之間的介面互動儘可能少,這樣在未來當模組介面發生變化時相關的修改調整工作量不至於再誇張,不過一般還是建議採用相容性設計來解決新舊代碼的遷移問題,這樣對於不同模組之前因設計升級而帶來的工作量相對較少,這種設計思路對於作業系統層級的軟體設計尤其顯得重要,大家看看Windows的相容性設計曆程就不難看出這種設計思路的影子,在Windows95的時候大量相容MS-DOS的設計、Windows98相容Windows95的設計以及以後的版本相容前面至少3個版本的Windows的各種應用的運行。
2.演算法:優秀的演算法可以直接決定問題解決複雜問題的思路的清晰度,大大降低代碼編碼的工作量,並且能夠極大地提升軟體的內在技術的含金量,有些極端案例,演算法還是決定這個軟體生死的決定性因素。
3.代碼邏輯分支處理:優秀的邏輯分支其條件以及迴圈嵌套邏輯最好不要突破三層的限制(受限於常人的腦力思維制限),現代程式的直接跳轉邏輯是基本不被允許的,分支邏輯控制在8個以內,對於超出上述標準的部分建議採用子函數分級來實現,這樣可以將不同的邏輯進行合理的切塊更加方便其他人的理解。
4.異常處理方法:通常對於軟體的除介面層以外的各層的異常處理的規則是大多數時候將異常向上拋送,個別時候需要將異常捕獲後直接輸出到日誌或者忽略的情況,而對於UI這層異常處理通常都是提示使用者相關的資料處理操作失敗,並且將錯誤的詳細資料通過使用者易於接受的某種表述方式通知到開發人員以方便開發人員來修複這個缺陷
譬如:對於Windows而言,當底層處理碰到異常後大家都會看到熟悉的BSOD畫面,並且通過CPU的陷進門機制來捕獲這些錯誤給出錯誤碼以及邏輯地址,並且可以DUMP出當時存在於記憶體中的資料資訊;
對於SDK層級的應用開發,特別在遠程支援的時候,更多地建議系統開發出x-Ray功能,對產生錯誤的情境進行全面掃描後完整地保留錯誤發生時段的全部環境資訊方便開發人員進行遠端分析提供必要的支援人員;
而對於Application層級的開發,一般都是將錯誤介面表現(Exception描述詳細資料以及UI截屏)以及系統日誌來進行全面地異常定位,方便後續的開發人員進行支援人員;
5.程式處理邏輯:簡單直接是程式處理邏輯考慮與設計時應該考慮的主流,現代的軟體開發特別是應用層級的開發更加突出這個中心思路,而對於架構層級的開發人員更多地是需要從開原始碼與社區中吸取設計與實現精化,在各種各樣控制流程轉模型以及設計模式之間尋求最合適的實現方案,從而確保代碼在簡單、直接、明了的思路基礎之上更增加了整體的可擴充性;
6.品質保證觀點以及實施,所有的代碼都必須通過嚴格的品質保證流程才能確保最後出來的是合格品,品質保證的觀點必鬚根植於團隊每個人的腦海中,在這點上開發人員往往存在以下幾種錯誤思路:
a.品質保證是專案管理人員以及QA應該做的事情,跟自己無關; 這種思路的錯誤之處在於過於片面地圈定了品質管理的人員範圍,正如同製造行業中推行全面品質管理TQM一樣,軟體開發的品質保證也絕對不是少數幾個人的事情,而是整個團隊對全生命週期的把握與管控。
b.品質保證僅僅是代碼品質的保證; 這種思路也是非常片面,而且這種思路在開發人員尤其是工作時間不長的開發人員隊伍當中存在的相當嚴重,過於忽略了在需求萃取、系統設計特別是人機互動介面設計方面的優越經驗。
c.品質保證僅僅是製造段(編碼+測試)的事情,跟其他階段無關;根據筆者所在企業對過去數百個不同內容項目的量化資料模型分析,我們發現軟體最終的交付滿意度的關聯因子主要是需求確認而引起,跟代碼製造段的關聯度並不高,從而從另一個側面說明了品質是跟隨需求走的,品質管控的重心是需求為主、代碼開發品質管控為輔的全面品質治理模型。
設定“神”的觀點主要是為了提高代碼的內在邏輯品質,無論從設計、編寫實現的角度來看整體品質確實是以“神”為主、以“形”為輔的開發過程,另外從筆者的經驗來看,之前大家推崇的開發管理模型中比較強調瀑布管理產品型管理模型,因此整體的品質上管控相對比較順利與容易,而最近多年的大量項目經驗告訴筆者,即便是產品型開發,為了適應快速開發的市場需求,Team Dev越來越推崇基于敏捷開發管理模型,並且迭代的周期也一般控制在2-4周左右,提出了“擁抱變化”的新理念,從而將客戶的滿意度提升到一個新的高度。
筆者在多年前進行一個知名的SAN儲存產品開發時,曾經經曆過一個開發配2-3個測試來進行品質保證(全部是黑盒層級的整合測試),可即便是這樣高的代價付出,最後整體的產品品質還是不高,在客戶處安裝已耗用時間長以後總是有各種各樣的疑難問題產生,在調試、測試以及做BUG FIX的時候總是覺得力不從心或者是有力使不上,正是當年的產品開發痛苦的品質管理經曆迫使筆者在後續的多年裡從軟體工程的全域視角來審視工程的品質,同樣在對日外包的開發中我們遇到另外一個比較相反的CASE,當時我們承擔了一個很CRITICAL的通訊群組件開發,為了確保整個項目的品質,按照軟體工程的理論,從需求理解、設計、代碼REVIEW、單體白盒、整合黑盒等不同的視角站在工程的角度來進行品質保證,卻驚奇地發現最後在客戶的環境下運行了6個月僅僅發現了一個很小的BUG,更為奇妙的是,在軟體工程的品質控制模型驅動下,我們從過去單純地看重代碼開發的視角放在整個軟體工程的生命週期的各個環節的控制把握,特別是將需求理解、系統設計等幾個源頭環節投入了更多的力量以及重視,從而將軟體工程品質的控制跟客戶的滿意度控制可以達到一個新的結合高度,軟體工程管理的迷人之處就在於能夠將普通的開發測試人員團隊在一種統一的思路指引下能夠製造出優秀的規模龐大的軟體,避免了軟體僅僅是由優秀人才才能夠生產的圈子,而其將過去的個人英雄式的手工作坊生產變成大團隊的工廠生產模式,真正地實現了軟體的產業化。