約定優于配置——軟體開發的簡約原則
2012-09-15 13:32 原文 簡體 繁體 5,099 次圍觀
工作快滿 1 年了。在剛從 CUHK 畢業的時候,我還滿懷悲壯地表示在中文大學飽受摧殘,各種 assignments projects 所寫的代碼已經超過了整個在武大的四年。而現在,wc -l 顯示的數字已經可以讓我十分蛋定,這一年的代碼量已經超過了過去所有學生時代的總和。回過頭來看一年前寫的代碼,真是慘不忍睹,恨不得把當時的自己拉出去暴打一頓。确實走了很多彎路,但我也是以收獲頗豐。
感觸之一就是怎樣編寫漂亮整潔的代碼。我曾經說過,我是個完美主義者,寫部落格的時候我要檢查以防出現錯别字,寫代碼的時候我會特别注意變量命名是否規範,甚至代碼縮進是否對齊。這大概已經屬于強迫症的治療範圍了。在現實項目開發中,整潔漂亮 意味着用最少的代碼,實作完整的業務功能,同時代碼是易于了解的。然而随着時間流逝代碼不斷被修改,系統設計的整體結構則逐漸衰弱。編碼從嚴謹的工程堕落為随性地胡亂砍劈。不重構,軟體就會慢慢腐爛。這一切是如何發生的呢?
歸根到底,還是源于軟體開發人員惰性。懶惰是天生的,例如 sofish 舉例過的一段代碼——
|
如果又有新的 condition_d,懶人複制粘貼一下就搞定。你可以同樣改成 switch,但本質上都是在寫重複的代碼。DRY 原則,即 Don’t Repeat Yourself,是編寫高品質代碼毫無疑問最重要的原則,重複是所有邪惡的來源。上面的代碼可以稍作修改
|
将重複的邏輯提取出來,抽象為一個獨立的函數,看上去就幹淨漂亮很多。是以抽象是一個很重要的能力。說一個差勁的程式員懶惰,并不是指他不情願編碼,事實上,他正不遺餘力的敲打鍵盤;懶惰展現在不願意思考,不想碰架構優化現有的系統。
為什麼需要架構?
架構是當事情變得複雜之後必須考慮的問題。如果你的桌上有 2 本書,那麼你怎麼擺放其實沒關系,你随手翻翻也能很快找到你想要的段落。如果你有幾百本書,那麼你就需要一個書架了。如果是一個圖書館,那麼就更需要一個合理的規劃,将書本分門别類,編号,建立索引,友善查找。軟體開發是一樣的道理,你得知道系統将要到一個什麼樣的規模,提前做好各方面的約定。例如選用一套開發架構,指定團隊的代碼規範。
約定優于配置
這是 maven 最核心的設計理念,很多語言架構都将其思想發揚光大。遵循約定雖然損失了一定的靈活性,不能随意安排目錄結構,不能随意進行函數命名,但是卻能減少配置。更重要的是,遵循約定可以幫助開發人員遵守建構标準。
例如 Yii 的典型項目結構是:
projectName/
index.php Web 應用入口腳本檔案
assets/ 包含公開的資源檔案
css/ 包含 CSS 檔案
images/ 包含圖檔檔案
themes/ 包含不同風格的主題
protected/ 受保護的應用檔案,主要代碼在這裡面
components/ 包含可重用的使用者元件,自定義類等等
Controller.php 所有控制器類的基礎類
Identity.php 用來登入認證的 'Identity' 類
config/ 包含配置檔案
main.php Web 應用配置
controllers/ 包含控制器的類檔案,MVC 中的 C
SiteController.php 預設控制器的類檔案
data/ 包含示例資料庫
schema.mysql.sql 示例 MySQL 資料庫
extensions/ 包含第三方擴充
messages/ 包含翻譯過的文本,适用于多國語言支援
models/ 包含模型的類檔案,MVC 中的 M
LoginForm.php 'login' 動作的表單模型
tests/ 包含測試腳本
views/ 包含控制器的視圖和布局檔案,MVC 中的 V
layouts/ 包含布局視圖檔案
main.php 所有視圖的預設布局
column1.php 使用單列頁面使用的布局
column2.php 使用雙列的頁面使用的布局
site/ 包含 'site' 控制器的視圖檔案
index.php 'index' 動作的視圖
login.php 'login' 動作的視圖
又例如 Yii 中對于 action 通配符的規範,XyzController.php 中若有一個名為 actionEdit() 的方法,那麼展現在網頁 URL 上,就是是除去 action 字首的動作函數名。即 http://www.mydomain.com/xyz/edit
更多的規範還包括變量、函數和類使用駝峰命名風格,即每個單詞的首字母大寫并連在一起,中間無空格。變量名和函數名第一個單詞全部小寫,而類的首字母需要大寫,例如:$basePath, runFunction(), LinkPager。對 private 變量和函數來說,以下劃線作為字首,例如 $_actionList
當然還有資料庫的規範——
- 資料庫表名和列名都使用小寫命名。
- 名字中的單詞應使用下劃線分割 (例如 product_order)。
- 對于表名,你既可以使用單數也可以使用複數。但不要同時使用兩者。為簡單起見,推薦使用單數名字。
如果風格統一,那麼代碼将是有規可循的。我們可以根據命名了解結構,根據結構了解建構的代碼原理。團隊的合作将是無縫的,多人 debug 也将沒有障礙。
我之前做的一個項目,就是因為缺乏遵循規範,而花費了大量時間和精力去做适配不一緻的接口參數,各種變量名稱的轉換占了整個項目代碼的很大部分。親自動手寫好一個站點并自己進行代碼維護,了解其中的弊端,經曆無數次的捶胸頓足痛定思痛,才知道最終如何改進才算架構“合理”。
關于重構
進度預估實際上是比較困難的一件事情。每當 Leader 問我這個子產品要幾天搞定時,我都支支吾吾。因為有時需要對舊代碼進行改造,或者說重構,而這些工作對于功能上沒有任何産出效益。在版本釋出的重壓下,快速疊代隻是我個人的一個期望而已。
軟體開發已經進化為軟體設計。在設計當中應當注重簡約的原則,少就是多。按照一定的設計模式來建構,總能達到事倍功半的效果。例如使用繼承、多态等面向對象手段,還有廣泛采用的工廠模式等等。又例如每個函數都簡單到僅僅 3 到 4 行長,函數的縮進層級不多于三層,每個函數隻做一件事,可複用,同時充分解耦。
好的代碼需要打磨。一個優秀的程式員,總能保證每一次 commit 倉庫裡的代碼比上一次更好。
關于技術布道
Fenng 曾經談過關于 技術布道 的一些經驗,其實就是“用影響影響影響”。那些大牛們孜孜不倦地對外傳遞大公司的動态、新的技術趨勢以及他們自己對技術的思考感悟,用自己的影響力去影響一部分具備影響力的人,再促使這部分人自發的去影響更大的目标群體。一些人之是以更牛是因為他們專注于自己做的事情,認為它是重要的,滿懷熱情,是以他有動力去優化自己的工作。相比之下更多的人隻不過是在應付。
我沒有那些令人景仰的牛人的魅力,我所能做的,隻是把自己所知道的總結出來,教給和自己合作的開發者,讓他們也能在技術上有所提升,這樣合作起來也會更輕松。我想這是件令人愉快的事情。
參考連結:
MVC架構導緻的詞彙表分裂
每一件意義重大的小事——讀《代碼整潔之道》