簡單設計落地三板斧

如果你認同 簡單設計的價值觀,我相信 解析簡單設計原則 對你來說很容易理解並接受,它不像面向對象設計原則(比如:SOLID)那麼晦澀難懂,它給你指明瞭一條明朗可通行的道路。即便如此,前進的道路依然不是一帆風順,尤其對於新手來說,怎麼將這些已經很接地氣的原則更高效地落地,從而創造更大的價值,本文我將分享幫助我們落地簡單設計的三板斧:TDD、重構和整潔代碼


價值體系

假如讓你去建造一幅巨大的廣告牌,你會怎麼做?從大框架來看,首先要打牢地基,再使用結實支柱做支撐,最後在頂部掛上廣告牌。地基和支柱是幫助完成目標的必備條件。那麼,如何實現簡單設計的核心價值?我們可以以簡單設計價值觀簡單設計原則做爲地基,並通過打造TDD重構整潔代碼 三大支柱來支撐起簡單設計的 “廣告牌”:


三大支柱

TDD

作爲極限編程的一項實踐,測試驅動開發經過被大量的開發者證明是一項具有實用價值的實踐。從廣義上講,TDD不限於開發人員在編碼的過程中先寫測試用例,然後驅動出代碼實現,就連我們拿起一個待實現的用戶故事[1],在腦海中開始構思如何去驗收這個功能,也是一個TDD的過程,只不過這個T存在於你的大腦中,沒有被可視化出來且不能複用。

本文我所要表達的TDD聚焦在編碼層面中的單元測試。它包含了三層含義:

  1. Test Driven Development
  2. Test Driven Design
  3. Task Driven Development

Test Driven Development

測試驅動開發,它是TDD在操作層面的落地方式,也是最普適的含義。它遵循一個基本流程:寫測試 -> 執行測試(紅) -> 寫實現 —> 執行測試(綠)。在TDD中融入重構步驟之後,它的一個具體詳細的完整流程如圖所示:

Test Driven Design

編碼如藝術,優秀的程序員即是一名設計師,也是一位藝術家

作爲一名用代碼改變世界的程序員,我們應該試圖將自己的設計思想融入到代碼中,讓代碼充滿生氣和靈性,從而遠離機械式的殭屍代碼。在解析簡單設計原則 一文中我談到設計不足和設計過度時所催生三類問題:

  1. 難以修改
  2. 難以測試
  3. 難以閱讀

TDD能讓我們在編寫測試的時候就開始思考即將實現的功能代碼的可測試性。試想如果我們在編寫測試階段就舉步維艱,此時不得不逼着自己去思考如何讓API能夠利於測試。這個過程主要面臨了兩方面的挑戰:

  1. 視角切換。從用戶視角出發,將腦海中的隱性驗收測試落地到代碼層面。
  2. API設計。如何讓API更加職責清晰、內聚,從而更加有利於測試。

這些挑戰對開發人員的設計思維提出了較高的要求,所以也能理解不少新手在起步階段頗爲痛苦,以至於他們會覺得TDD降低了開發速度,對它的價值產生了懷疑。

從我個人經驗以及身邊一些大牛身上總結出一個結論:掌握TDD最好的捷徑是刻意練習。所以如果你剛起步,不要氣餒,找一些Kata勤加練習[2]

Task Driven Development

任務驅動開發,強調的是將大任務拆解成小任務。人的大腦在處理足夠簡單的問題的時候(比如1+2-3+4-5 = ?),能夠快速給出方案。然而,面對較爲複雜的問題的時候(比如2-1*5*3/2+2-3/2-2/1*5+4-5 = ?),大腦難免捉會襟見肘,此時就有必要藉助一些輔助工具來做到事半功倍。

任務驅動的方式會用到一個思維工具 – Tasking[3]。在練習TDD時,建議你將待完成的任務進行分解,然後將分解後的子任務可視化出來。可視化的好處之一是它可以作爲溝通的工具,去收集反饋,進而完善自己的思路。任務拆解之後的好處是,待實現的功能更加小而單一,有利於編寫測試。

Tasking同樣需要刻意練習,它對分析性思維提出了一定的挑戰,練習分析性思維的四步法:

  1. 定義問題 - 清楚定義問題
  2. 分解問題 - 將問題進行分解
  3. 關聯問題 - 通過輸入和輸出尋找子問題的關聯關係
  4. 限界問題 - 識別出子問題的邊界,明確假設和結果

關於TDD的示例,歡迎觀看我錄製的視頻[4]

重構

重構,它是極限編程中的一項實踐,Martin Flower在 《重構:改善既有代碼設計》[5] 一書中對重構進行了全面的定義。它提倡我們對代碼最佳實踐充滿敬畏之心,在不改變軟件行爲的前提下去修改代碼,不斷改善代碼的設計,提升軟件的響應力

作爲程序員,我們經常在修改代碼,在修改之前,建議你先問自己四個問題:

  1. 軟件已經工作,還需要修改這段代碼? - 軟件可工作,可能有壞味道
  2. 如何識別這段代碼浮現出的壞味道? - 換味道是什麼
  3. 針對壞味道,我們應該怎麼修改? - 怎麼去壞味道
  4. 修改完之後,如何確保功能沒有發生變化? - 軟件可工作,壞味道變少

四個問題環環相扣的,始於目標,終於目標。你若能給出答案,並形成閉環,便實現了重構的核心價值。通常最難回答的是最後一個問題,以至於遲遲不敢下手,導致軟件逐漸惡化。所以重構提倡重構要在測試的保護下進行,人工測試亦或自動化測試,只要能給出正確的答案。

重構是一門手藝活,在日常編碼中,你應該始終保持警惕,積極思考上述四個問題,另外輔以大量的刻意練習[5],同時我強烈推薦你以*《重構:改善既有代碼設計》*[6] 這本書作爲起點。

結合TDD,重構大有用武之地,測試先行保駕護航,重構演奏,方能唱出悠久的歌聲。然而重構到什麼程度?讓整潔代碼來回答這個問題。

整潔代碼

整潔代碼,從其字面來看是要編寫整潔的代碼,但這個問題仁者見仁、智者見智,很難有一個標準答案。回到我們文章的初衷 – 落地簡單設計,所以整潔的代碼至少是:

  1. 儘量不重複
  2. 儘量揭示意圖
  3. 儘量簡單的

小到變量命名,大到類交互設計,我們應該在意識中不斷強化對以上三點的認知,在實踐中養成良好的編碼習慣。

Robert C在*《代碼整潔之道》[6] 一書中提供了很多案例,另外《編寫可讀代碼的藝術》*[6] 也是一個很好的開始。理論結合實踐,在日常開發中,建議你在團隊中組織Code Review[7],它是一個難得的學習提升機會。


價值着陸

TDD、重構和整潔代碼並不能直接讓我們設計出來的代碼就天生符合簡單設計。TDD帶我們開了一個頭,一旦開始了,在過程中不斷地審視自己的代碼,並通過重構來讓代碼變得整潔:

歡迎你以文中提到的案例和網站作爲開始,進行大量的刻意練習從而讓簡單設計的核心價值能夠着陸你所開發的軟件,提升軟件的響應力。


註釋

  1. 用戶故事是極限編程中的一個實踐,請參閱 我在ThoughtWorks中的敏捷實踐

  2. 關於編碼Kata,歡迎訪問 http://www.cyber-dojo.org/

  3. 有關Tasking更多解讀,歡迎閱讀ThoughtWorks仝鍵老師的 像機器一樣思考系列文章

  4. 我已經將 TDD實現斐波那契數 的視頻發表於B站

  5. 關於重構的練習,歡迎以 GlidedRose 案例作爲開始

  6. 關於編程方面的書籍,歡迎從我的GitHub programming-books 庫中獲取

  7. Code Review是項非常有價值的編碼實踐,它不僅能夠促進團隊互相學習,還能防止代碼庫惡化,更多內容請參閱 我在ThoughtWorks中的敏捷實踐


Posted by 袁慎建@ThoughtWorks

版權聲明:自由轉載•非商用•非衍生•保持署名 | Creative Commons BY-NC-ND 4.0

原文鏈接:http://sjyuan.cc/three-core-practices-of-simple-design/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章