好的programmer寫作的程式碼,必定是條理分明、敘述清晰、邏輯清楚。
一份好的程式碼,本身就已經清楚說明目的和用法。
兩個都懂某程式語言的人,就像兩個都懂英文的人,能夠透過語言本身清楚地溝通。然而,我們若講或寫出一段別人聽不懂或看不懂英文時,我們會清楚知道是自己的問題。但許多寫程式的人卻因為寫出別人看不懂的程式碼而沾沾自喜,真是一件怪事!?
當然,溝通的基礎是建立在雙方都懂這個語言,並且知道慣用的標準為何。
多數的programmer都知道,debug很花時間,許多專案都浪費大把的時間在debug,好不容易找到問題,修改好了,卻又因為忽略某些情況再次出問題,修修補補的程式碼既難看又造成更多問題。
防禦工事就是在撰寫程式碼的當下,就盡可能一次把事情做到定位,因為只有當下最清楚哪些問題可能發生,若因為拿時間有限當藉口而偷懶,省下撰寫預防用途的程式碼,日後將會付出更大的代價,也就是無謂地增加開發成本,更可能造成專案因此延宕。
舉例來說,一個小程式接受使用者輸入兩個數字,並且相除。
這個程式很快就能寫好交差。
a = get_user_input();
b = get_user_input();
print a/b;
假設這個程式碼可以運作,但那一定只有在限定的狀況下。
也就是使用者輸入的第二個數字不得為零。
我們可以偷懶而將問題視而不見,反正老闆/客戶可能永遠不會發現,就算到時候被發現了,再回頭修改不就好了,這世界上哪有不會出錯的程式呢?看看微軟的BSOD,不就是經典中的經典嘛。
但想想看,當程式碼變成幾千行、幾萬行,甚至幾十萬行的時候,這個小錯誤要找出來會花掉多少時間人力阿。
在撰寫程式的當下做好防禦工事,其實很容易。
只要加上些假設條件的判斷。
a = get_user_input();
b = get_user_input();
if (b <> 0) {
print a/b;
}
else {
print "error: devide by zero";
}
當然還可以再想得更周到,讓使用者可以重新輸入。
改寫如下。
a = get_user_input();
b = get_user_input();
while (b == 0) {
print "warning: input must be non-zero value";
b = get_user_input();
}
assert(b <> 0);
print a/b;
因為使用者輸入0的時候,程式會要求重新輸入,所以我們在印出a/b的時候省略一次if判斷。但是為保險起見,加入assert的語法,以免前面的程式碼在某次的修改之後失靈,又再度發生錯誤。
assert再不同的程式語言的編譯器會有不同的實作,這個機制讓我們可以撰寫一些限制條件的驗證,在development階段可以方便debug發現問題並及早修正;而在production的階段,某些程式語言的編譯器允許選擇性地除掉這些驗證,以減少不必要的效能支出。
哪些情況的防禦可以用assert呢?
一個簡單的判別就是,當一個限制條件的判斷,在程式正式發行時就可以忽略不管,那麼就可以考慮用assert,否則要用if-else或其他方式作永久性地檢查。
* 了解一個語法適用的時機及意義,不要濫用及錯用。
* 避免使用非語言標準的語法、函式庫。
* 盡可能考慮周詳並在程式碼清楚表達出來。
* 寫出其他人能夠直接看懂、不必猜測的程式碼。
* 不要讓使用者有機會發生可以預知的錯誤,雖然錯誤的發生可能是在很愚蠢的狀況下,但現實就是真的有人會那麼蠢。
在撰寫程式碼的同時,需要多思考這段程式碼的防禦工事是否足夠,那些情況下會被攻破,在當下就盡可能做好準備工作。寫出日後更容易維護、更少出現問題的程式碼,才是合格programmer應具備的能力。
參考文獻
- Code Craft: The Practice of Writing Excellent Code
2009/12/3
訂閱:
張貼意見 (Atom)
-
►
2012
(21)
-
►
一月
(17)
- 選擇 Ubuntu 的套件庫來源
- 2012 新年快樂!合歡山飄雪囉!
- 解決 pdf 中文字無法在 Ubuntu 文件檢視器顯示問題
- SOPA 連結整理
- Node.js 與 IIS 初探
- Amazon EC2 現在也提供免費的 Windows Server 試用方案
- 讓 reStructuredText/Sphinx 輸出 mobi (Kindle) 電子書格式
- 使用 Watchr 讓持續測試工作更容易
- ASP.NET + iisnode + node.js + express + mongodb(mo...
- node.js, npm, iisnode on Windows 7
- Sortfolio 媒合全球網站設計師及發案公司的線上服務
- Dokuwiki + S5 自動產生投影片
- 寒冬保暖的運動襪 titan 限時7折優惠
- WIRED 雜誌推出中文版!
- Pubu 飽讀電子書 App 新服務上線,免費雜誌大放送
- Mozilla Add-on Builder 快速開發自己的 Firefox 瀏覽器外掛
- 更適合閱讀的 Dokuwiki Readability 樣板發佈
-
►
一月
(17)
-
►
2011
(197)
-
►
十二月
(17)
- 使用 Google AdSense 西聯匯款,取款心得小記
- Java 專案自動化建置之 Gradle 與 Eclipse 整合篇
- Wijmo - jQuery UI Widgets 網站前端開發的新利器
- Plupload 支援網頁多檔同時上傳的開發利器
- Drush 安裝設定以 Ubuntu 為例
- OpenChurch 教會網站架設套件(以 Drupal 6 為基礎)
- 聖誕節網頁應景的 JavaScript 雪花紛飛效果
- Google 聖誕節主題:搜尋 let it snow 讓瀏覽器下雪
- 天上掉下來的免費 Online IDE --- Cloud9
- Linode 傳輸速度測試
- jQuery CodeMirror Plugin
- CodeMirror 2 runmode (highlight only) with gutter
- 再談電子書原始碼製作:程式設計教學篇
- 使用 Gradle 快速建立 Tomcat 開發測試環境
- 使用 iPad 製作 PDF 及 EPUB 電子書,作者輕盈零負擔!
- 再思考自助出版電子書該如何「設計封面」 與行銷?
- 開放源碼電子書與 EPUB 幕後排版
-
►
十一月
(19)
- [試用] 2011雲林路跑賽,體驗 titan 功能慢跑襪
- 綠林新款電子書閱讀器 Greenbook EZRead Touch 測試
- DD-WRT Repeater Bridge Mode 讓無線訊號範圍更廣
- [試用] 台灣製造才是好襪!titan 全方位運動襪實測
- 很棒的 GitHub for Mac 發佈新版
- 信仰需要仰賴閱讀與思辨尋找真理
- GitHub 也推短網址服務 git.io
- 一分鐘認識 Chicken Scheme
- 用 Groovy + SwingBuilder + JEditTextArea 快速打造輕量化程式碼...
- 用 Readability 讓網頁更容易閱讀
- Groovy + SwingBuilder 筆記 20111117
- MacVim 當蘋果遇見歷久彌新的老牌文字編輯器
-
►
十二月
(17)
0 意見:
張貼意見