作者:郭任超/ 有勁生物科技
隨著科技的進步與雲端數據應用的普及,未來在這個領域,如同英文溝通能力於商務領域那樣,具備基礎的程式撰寫能力也將會是必備的基本技能。學習程式編碼(coding)也是一種訓練利用邏輯進行思考及解決問題的方法。透過良好程式撰寫習慣的養成,不但可大大提高工作效率,也可減少不必要的失誤。
1. 事前規劃
著手撰寫程式之前,先規劃好程式執行的流程,將實際需求拆解成幾個比較小的「User story」;從使用者的角度來建立需要實現的功能,並以此推估所需的時間成本,同時注意各個story之間的相依性。針對比較複雜的數據結構、物件或子程序,則可利用圖形來輔助說明 (ex.使用UML來繪製),比單純用文字描述要好。
2. 模組化
把複雜的大問題拆成數個容易解決的小問題來一一處理,之後再將解決方案彙整,讓大問題變得更容易解決,這整個流程就是模組化的一種過程。
通常模組化的做法是把處理共同問題、或具有相同行為的函式 (Function) 依照相似性進行分組,集合成一個類別 (class)。各類別皆遵循單一職責原則 (Single Responsibility Principle),一個類別只負責一個responsibility,實作上盡可能依照Robert C. Martin所說的每個類別應該僅有一個可變因素(A class should have only one reason to change)的原則,來進行職責的分配。如此一來,未來針對某一類別進行相應的更新或加入額外需求時,便不會因一個職責相關的改變,而牽連到其他程式碼,破壞了整個系統的運作,從而可達成高內聚、低耦合的目的。當所有職責都有適當的區分時,程式也會變得更容易擴充與維護。
3. 不要重新發明輪子
“Don't Reinvent The Wheel”(不要疊床架屋)的意思是說,如果已經有大家都公認不錯的程式碼或函式庫,很多情況下就足以應付多數需求,不需要再重頭建構,以免浪費無謂的時間。
對於經常出現的問題,我們可利用已有的軟體資源:例如數據資料、程式結構、設計模式、軟體工具與軟體環境等,來提高程式組件的重覆利用性。此外,功能函式也要盡量提取出來,不要全部寫在同一支程式裡。
4. 程式碼的可讀性
程式碼的撰寫原則是要讓使用者在短時間內就能理解並弄懂。但對大部分撰寫者來說,可能覺得程式只要能正常執行就好,而選擇忽視程式碼編排與重要規範,想要留待日後有時間再來整理,但這些都將造成之後維護的困難與耗費許多額外的除錯時間。
改善程式的可讀性有許多途徑,像縮排分段、名稱命名、註解以及利用區塊及函式組織程式碼等等幾個基本項目都是。
a. 適時調整縮排與斷行,每行程式碼以80個字元為基準。適當的程式碼寬度不但方便閱讀、不用擔心被使用端(terminal) 的編輯器自動換行,還可顯著增加排版上的美觀。
b. 命名規則要始終一致,並使用有意義的名稱,讓閱讀的人很容易從名稱就可以了解該函式與變數的功用及意圖。
c. 將變數的作用域限縮到最小,只有在需要使用變數時才宣告及初始化,並盡量減少使用全域變數,改採函式閉包 (Closure) 或物件,來降低不同模組及函式引用時,因變數名稱重複所導致的命名污染。
d. 利用註解來描述作者想法、解釋晦澀難懂的演算法、或是紀錄程式碼的缺陷。註解應保持語意的精確與簡潔,使程式碼更容易理解。但若程式碼本身就已足以讓人了解用途,那麼不加註解反而比較恰當;要知道:一個好程式比「壞程式加好註解」更好。
e. 透過類別和函式將程式所需的功能切割及封裝,一個函式只做一件事,且函式的語句結構要越簡單越好。有需要運用同樣功能時,只要透過引用類別並呼叫函式便可達到目的,如此才能有效提高重複利用率,並有利於維護。
f. 確立共同的規則和術語,開發中的交流和協作都需要有共同慣例和詞彙基礎,如此便可加快開發速度,並降低維護的困難度。
5. 版本控制
軟體開發過程中,版本控制系統有助追蹤過程、對檔案文件差異進行快照/同步/合併/回復先前狀態,發生問題時,也方便藉由查看時間點或開發者提交的修改項目來找出原因所在。如此,即便是一人開發,也能夠輕鬆維護開發環境。
版本控制,一般人常見做法就是檔案一有新的變更就複製一份存放,再以不同檔案名稱命名。一開始可能還記得哪裡做了更動,但過了一段時間,程式碼越來越多,甚至連上一次的更動都想不起來了。在許多人共同開發情境下,即使每次都是從共同存放的位置取出檔案修改,可是當修改後上傳時,如何確保同時間沒有其他人也在上傳檔案,這時候互相覆蓋檔案的情況就很可能發生。
目前流行的分散式版本控制系統,例如Git、Mercurial,開發者可以同時扮演貢獻者,以及擔任接受其他開發者提交程式碼的公共儲存庫;儲存庫之間也能互相傳送,並透過不同的工作流程,靈活協作方式。
而根據開發需求還可以建立不同分支 (branch),例如:在進行除錯的同時也想添加實驗性的功能特性,那麼就可以建立分支來區隔不同的工作,如此便不必擔心改到同一個檔案。我們可以在不同分支之間反復切換,在確保已完成的分支特性通過測試後,就可將不同分支合併,發佈或進行下一階段的開發。
6. 重構
重構 (refactoring) 主要目的就是為了提升程式碼的可讀性,或簡化結構、清理冗餘無用的組件,這些都是在不影響程式原有行為的原則下進行,讓日後的因應修改或擴充更加容易。
什麼時候該考慮重構?其實,重構是開發過程中隨時隨地都在進行的,為的是讓後續開發更容易進行,而不是特別另外安排時間來做的工作。對於何時進行重構則沒有精確的規範,在開發過程某些適當時機點就可以搭配重構一起進行;例如:
a. 添加功能的時候
當原本的設計方式無法讓我們依照需求添加新功能時,程式碼就必須做調整以改善現有設計。
b. 修復錯誤的時候
程式碼有錯誤,通常代表設計不合理,或是對程式碼誤解所導入的程式錯誤。透過除錯的過程重新理解程式碼之後,就知道如何用更簡單易讀的方式改寫程式碼。
c. 審核程式碼的時候
審核程式碼有其重要性,通常由審核者檢視程式碼,找出開發者思慮不周全的部分,並提出修改建議。
d. 三次法則 (rule of three)
此一法則由Don Roberts所提出,是程式碼重構的經驗法則。其要求是,當程式碼片段重複時,允許直接複製貼上程式碼一次,但如果相同片段重複出現三次以上的時候,就必須將之提取出來做成一個子程式。
7. 持續不斷學習
資訊技術進步非常快,平常可以多參考別人公開的原始碼、學習新語言、了解目前發展趨勢,不要滿足於單一種程式語言及開發環境,藉由持續吸收新知來維持思想上的開放與活力。
參考文獻:
Robert C. Martin. (2011). The Clean Coder: A Code of Conduct for Professional Programmers. (Prentice Hall)
Dustin Boswell, Trevor Foucher. (2011). The Art of Readable Code. (O'Reilly Media)
Scott Chacon, Ben Straub. (2014). Pro Git , 2nd ed. (Apress)
Martin Fowler, Kent Beck, John Brant, William Opdyke, don Roberts. (1999). Refactoring: Improving the Design of Existing Code. (Addison-Wesley Professional)
留言列表