《Code Complete》:程式設計者必讀的經典之作

Code Complete Second Edition書名:Code Complete, Second Edition
作者:Steve McConnell
譯者:譚詠歸
出版:Microsoft Press; 2nd edition (June, 2004) / 學貫
語言:英文版 / 繁體中文版

Code Complete 是一本很不可思議的好書。書中的內容,沒有模糊不清的理論,而是立即可運用在現行專案或程式中的各種技術。有太多太多的實用知識,完整詳細地解答了我長久以來的疑惑與困擾。

軟體的開發,存在許多不同的階段 (Phase) 與面向,Code Complete 的主要內容,是著重於軟體開發的建構 (Construction) 階段。Construction 一般常會被認為是進行 Coding 或 Programming 的階段;但是在這個階段中,其實還包含了架構設計、細節設計、建構規劃、單元測試等等許多不同的活動程序。

書中的內容從軟體建構的定義開始介紹,從 High-Level 的角度論述「設計」在建構階段中所扮演的角色,與實際可用的設計程序。接著每個章節探討一個主題,由最常見的 Class 與 Routine 設計與實做層面開始,逐步論述各種設計與實做上的考量。而後又討論了 Defensive Programming 與 Pseudocode Programming Process 兩個相當有用的設計方法。

接續的章節往 Low-Level 的建構層面邁進,先以程式中最基本的組成元素,變數的使用開始論述,包括變數的一般使用原則、變數命名、一般資料型態,與非尋常資料型態的變數。變數的設計與使用,經常容易被忽略或是獲得比較少的注意,但是對於一個程式的優劣勝敗來說,變數絕對是具有相當程度的影響力。接著介紹程式中很重要的控制元素,也就是各種控制結構的使用。從直述式結構、條件式結構、迴圈式結構開始,再接續討論非尋常的控制結構、表格驅動方法,與結構式程式設計的一般性原則。結構式程式設計主要的立論在於,無論任何的控制流程,都應該能夠從 Sequence、Selection 與 Iteration 三種架構所建構出來。

接續的章節,再重新回到 High-Level 的觀點, 闡述軟體品質的特徵、專案大小的取捨、建構階段的管理、整合技術,如何深遠地影響到整個專案的運作,與進一步的建構階段。然後是 Developer Testing、Debugging、Refactoring,以及常被過度強調的 Code Tuning 考量與技術。還有一個章節討論較為少見的協同式建構 (Collaborative Construction) 流程。到了書中的最後一個部分,討論的則是比較屬於心理層面的主題,包括很重要也很具爭議性的程式寫作風格與版面配置,以及如何達成不說自明 (Self-Documenting) 的程式碼。最有意思的部分,是書中的最後兩個章節,分別討論了個人特質對於程式建構的影響,與整本書總結整理的部分。

貫穿全書的重要理念主要有以下幾點:

  • 克服複雜度

    軟體設計與建構的一個主要目標,就是克服複雜度。 許多程式設計實例背後的動機,都是為了能夠降低程式的複雜度。而降低複雜度,可以說是成為一個有效率的程式設計師,最重要的關鍵。大部分人的思考容量是有限制的,所以我們應該盡力最小化,一個人在同一時間內,需要思考的程式數量。可以說所有軟體設計技術的目標,都是在於將一個複雜的問題,分解成許多簡單的部分。

    一個專案的失敗,通常可能是導因自不良的需求、不良的計畫、不良的管理等等因素。但是如果失敗的原因主要是來自技術面的話,那麼這個原因通常是「未被控制的複雜度」(Uncontrolled Complexity)。因此,盡力控制複雜度 (Manage Complexity),可說是在軟體開發中最重要的一項議題。

    而一個測量程式複雜度 (Programming Complexity) 的方法,就是你為了瞭解一個程式,而必須在同一時間之內,保持在心裡思考的物件的總數。這種「心智把戲」(Mental Juggling) 的行為,就是程式設計最困難的面向之一,也是程式設計為何需要比其他活動更多專注力的理由之一。有兩個辦法可以對付複雜度: 其一就是藉由更多的「心智練習」以增進操弄心智把戲的能力,然而程式寫作本身就是一件足夠的心智練習,因此能增進的幅度相當有限。其二是降低程式的複雜度,以及為了瞭解它所需要付出的專注力。

    根據 Edsger Dijkstra 的論述:大多數的程式設計,都是意圖補償人類極為有限的腦容量。程式設計最佳的人,是那些瞭解他們自己的腦袋有多小的人。他們是謙遜的。學習越多以彌補不足的腦袋容量的人,就會成為越好的程式設計師。越是謙遜的人,越能夠快速的增進。

    『Good programmers are humble.』

  • 程序 (Process) 的重要性

    在一個小型的專案中,個別程式設計師的才能,是影響軟體品質的最大因素,其中某部分的成功因素,可以歸功於個人選擇使用的程序。然而在比較大型的專案中,相較於個人的技能來說,組織化的特徵程序能夠帶來更大的影響。

    即使是一個很好的團隊,他們所能夠貢獻的能力,並不是單純所有個人能力的加總而已。人們在一起工作的方法,會決定他們的能力是有相加的效果,或是相減的效果。程序之所以對於軟體開發很重要的原因,在於品質必須要從軟體專案的第一步就建構於其中。

  • 程式撰寫考量的出發點,應該以「人」而非「電腦」做為第一優先考量

    程式碼在很多情況下都會被閱讀,無論是自己或其他人,在修改、除錯、維護的時候,都會需要閱讀程式碼。所以想盡各種辦法,使用各種技術,使程式碼具備可讀性、易讀性是很重要的主題。你應該要花費心力在撰寫良好的程式碼上,以致於你可以只做一次,而非需要重複又重複地閱讀差勁的程式碼。

    沒有一個單一技術的應用,可以區別出一個易讀的程式或不易讀的程式,但是由許多小部分閱讀性的改進,能夠累積出重要而可觀的成效。程式設計中,較少部分的工作,是為了撰寫程式讓電腦能夠閱讀它;而較多部分的工作,是在於使得其他的人類能夠閱讀它。因此,程式設計師在撰寫程式的時候,應該要偏好「閱讀時的便利性」,而非「撰寫時的便利性」。

    『Any fool can write code that a computer can understand. Good programmers write code that humans can understand.』

  • 迭代 (Iterate)、重複

    「設計」是一個奇特的問題 (Design is a wicked problem)。奇特問題 (Wicked Problem) 是指,唯有當這個問題被解決之時,才有辦法清楚的對它做出定義。聽起來像是似是而非的矛盾一樣,而「設計」正是屬於這種類型的奇特問題。設計不會是一開始就如泉湧般直接而完整呈現的,通常會經過許多重複檢視、討論、實做程式碼的經驗後,而逐漸演化與改進的。因此,所謂的設計,其實是一種迭代的過程。

    單次的設計通常無法達到最理想的結果;設計本身就是一個不斷反覆琢磨的程序。使用某個方法解決了問題之後,往往可以對這個問題本身獲得更好、更深入的洞察力,可以使我們學習到解決這個問題,更好、更適切的方法。 所以我們可以說,設計本身是一種啟發探索性 (Heuristic) 的程序,而非決定論 (Deterministic) 的程序。這一點,對於軟體專案來說亦然。

最後,作者提到相當重要的一點,就是必須將各種書中的技術視為工具箱中的工具,然後使用自己的判斷,選出適合進行各項工作的工具。這本書裡討論了很多好的程式實例,但不是意指需要拿來當作嚴格遵行的一組標準;而是使用這本書當作討論的基礎,當作良好程式實例的資料全集,以確認出對自己專案最有利的程式實例。

多數的程式設計書籍,都是教導「如何把程式寫好」,然而卻僅有少之又少的書籍教導「如何寫出好程式」。這不是文字上的把戲,而是根本上的不同立足點。一本普通的 C++ 書籍,會教導讀者虛擬與多型的使用語法;一本優秀的 C++ 書籍,會教導讀者虛擬與多型的使用語意;更深入的書籍,或許會教導讀者虛擬與多型背後的設計思維與實做細節。然而,卻鮮少有書籍教導其合適的使用時機,並且能夠和其他可選擇的做法,做優缺點的比較。

什麼樣的情境下使用 Inheritance 會比 Containment 好?到底應該使用繼承類別以達成 Virtual Function 的效用,還是使用 Function Pointer,還是簡單的 Case-Switch?要傳入單一個物件當作參數,還是傳入多個一般資料型態變數當作參數比較合適?要使用深層的巢狀控制結構,還是使用其他控制結構減少巢狀層數?什麼樣的程式才叫做最佳化?怎麼樣才能有效的運用 80/20 法則於最佳化的程序中?還有更多更多可能你我都曾經在腦袋中一閃而過的疑慮。

如果,這本書不能夠提供一個令所有人滿意而一致認同的解答,至少它能夠成為一個驅動思考的啟發點

Code Complete 目前也有繁體中文版本囉!書名是軟體建構之道。如果你平時的工作非常忙碌,沒有太多時間可以閱讀書籍,一年只能選擇一本書來讀的話,我誠心誠意百分百推薦這本!即使是在兩年多前就閱讀過這本書,現在偶爾拿出當時所做的筆記與摘錄翻閱,仍然能夠從中獲得不少煥然一新的思考啟發與心得印證,絕對是一本值得一讀再讀的好書!

20 Replies to “《Code Complete》:程式設計者必讀的經典之作”

  1. 哈 前幾天去拜了這一本….不過

    不知道版大有沒有推薦的遊戲開發知識相關的書籍

    廳主管說 只著眼於某一套工具 眼界會太小

    本身是想從DirectX開始了解

    但是也想知道如果從 遊戲程式開發來說

    是看一個學一個 還是有其它方式

    因為總絕得 看一個學一個總是很被動

  2. @JK:
    基礎的話我推薦這兩本
    -Java Game Programming 建立遊戲的演算法與框架
    -遊戲之旅 我的程式設計感悟
    都是有點早的書,可能不容易買到
    第一本雖然是JAVA,不過講到很多遊戲程式的基本觀念,其他語言也適用

    遊戲程式開發我覺得是看你想做什麼遊戲再決定研究哪一方面,從底層開始做也一樣
    例如文字AVG要有簡單易用的script系統,自己從底層做可以參考NScripter、YU-RIS等引擎的設計
    要做彈幕就要研究如何管理大量子彈,以及提升繪圖效能

  3. @Shark:

    感謝你!
    遊戲之旅這本書我有在天龍查到, 有空會買來看看, 目前書堆的有點多
    恩恩, 似乎是明定好目標之後 在朝那著手會比較知道該怎麼作

    有時候在作遊戲,總是這邊加點功能,那邊修點bug,後來去玩別人加遊戲
    就覺得ㄝ…為啥他這個看起來好漂亮,也好好用,因為遊戲是用script
    language開發上層,所以有時候會有底層的限制,後來就去看了底層,
    只是因為對引擎的架構不是很熟悉,有時候看了很久才會知到為什麼
    需要這些前置作業, 此外,我還想問,就是會有甚麼推薦的方式來增加自己
    對於工具上或是知識上的不足嗎?…遊戲這一塊感覺很大,我可以明定
    自己要從3D作起,只是 希望平時無聊會逛的網站, 但是不是很清楚
    是不是有甚麼人的blog總是會一起分享這些資訊.

    我自己是大多都看官方網站, nvidia, python…偶爾會問問同事有
    沒有甚麼之類的網站可以參考, 有時候就會發現很多不知道的技術!

  4. 遊戲引擎基本架構就是我列的第一本書了,我在博客來看到還有存貨
    底層最基本的不外乎繪圖、聲音、輸入三部分

    增加知識的方法除了看資料以外,我常常自己寫程式做實驗,像是文字編碼和Unicode我就用printf把每個byte的值印出來研究
    另外可以請教一些實際在創作的人

    3D最重要的是繪圖流程,繪圖流程熟了再學應用就很容易,不懂的地方就做實驗去試
    我研究過3D繪圖流程但沒試過用3D模型畫圖,因為目前沒有要做3D遊戲
    這是我知道有在做3D的團隊
    http://zestostudio.blogspot.com/

    點我的暱稱是我所屬的團隊WKY,要討論我現在在做的東西可以去那裡,在別人的blog討論不太好

  5. @JK:
    我認為學習遊戲程式設計的知識,就像是練武功一樣,需要花費許多時間心力勤加練習基本功,一點一滴地累積「內力」,否則就算你學會再多的程式語言、繪圖 API 或遊戲引擎,到頭來可能也只是中看不中用的花拳繡腿而已。

    主要還是看你想要朝哪個方向發展。在遊戲程式設計方面,中文的網路資源仍然是少之又少,所以不免還是需要多閱讀國外遊戲開發網站的文章,才能夠獲得第一手的理論與技術資訊。至於書籍的話,如果你想瞭解遊戲系統架構的話,我會推薦《Game Architecture and Design》與《Game Coding Complete》這兩本書。

    @Shark:
    謝謝你提供的資訊。

  6. 這本書第兩版我都有買中譯本,

    第二版的繁中翻譯得很差,買回來很後悔
    同樣是第二版,簡中版就翻譯得比較好,且較便宜

    順便一提,
    wicked problem 譯成「難纏的問題」或「邪惡的問題」應該比較貼切
    我買的第一版是旗標出的,就是譯成「難纏的問題」

  7. @York:
    你好,

    謝謝你提供的資訊,想購買繁中或簡中版本的讀者可以參考看看~

    嗯,wicked problem 翻成「難纏的問題」的確比較貼切。

  8. 您好,

    很懊悔現在才發現這本書,很多人都強力推薦要看看這本書

    正在煩惱應該訂繁中版還是英文原版比較好?

  9. @youlanasi:
    你好,

    若你可以通順流暢地閱讀英文技術書籍的話,我會建議直接閱讀英文原版比較好。

  10. 謝謝回覆!

    從amazon.com那邊試看了幾版英文版,
    一般都可以理解到它想表達的意思,不過還是有一兩個單字如metaphor不會。

    這樣的話是不是中文版會領會比較深?
    但感覺看英文原版會學到不少做software project時應該要懂的單字

    剛剛看到樓上說第二版的譯本好像有點瑕疵這樣…
    真糾結呢

    中文譯本有沒有英文單字的註解?

  11. @youlanasi:
    我沒有讀過中文版的書,不確定是否有英文單字的註解。建議你到書店實際翻翻看中文版,如果可以順利看完一個章節的話,我想在理解上應該不會有太大的問題。

    若你只有幾個單字不懂的話,其實讀英文版也很 OK 啦~

  12. 看过半路的部落格,受益匪浅。感谢分享~。
    在Youtube上看过你们的新游戏,勾玉忍者,非常棒哦(可惜没有apple的设备,什么时候可以出Andorid版本?)加油 XD ~ 支持你们~
    推荐书目非常好,可不可以单独建一个Page分享半路的好书呢 ?:-)

Leave a Reply