從TDD裡面學到的程式編寫順序

Rex Wang
Dec 1, 2020

--

最近有點忙亂,有段時間沒有寫新的文章,今天紀錄一下顛覆的程式編寫順序。

補充說明:

[2020/12/05] 這個方法在Uncle Bob的著作-Agile Principles, Patterns and Practices in C#裡有提到,叫做基於意圖的程式設計(intentional programming)

在Clean Coder 裡面 Uncle Bob提到自己向Kent Beck學習TDD的情況,也啟發Uncle Bob設計了一些練習TDD的Kata。Uncle Bob在書中提到,他跟Kent Beck進行 Pair Programming,Kent Beck先思考尚未編寫的class與method要怎麼使用,把使用方式或是API的組合方式,寫在Test Case裡,每當發現缺少什麼Production Code,就編寫足以通過測試的Production Code,然後就回到Test Code繼續組合他想要的API,如此不斷往返,慢慢的Production Code完成。

在幾次課堂與社群活動上,許多大師、神人也是使用這樣的開發方式,讓我從中看到傳統開發方式的差異,也是個人開發技巧可以提昇的部分。先擱置你的團隊適不適合TDD,這個開發方向的改變,是有可能大幅改善團隊的開發效率。

也許是因為書籍的編寫方式,我們寫程式多半是先從單一的 class寫起,再往內編寫我們想像中的 method;而每一個class跟裡面的method就這樣一個一個寫下來,如下圖的CreditService 與 TicketService;再一起組合API,如下圖的OrderService,最後再簡單驗證一下之前寫的method行為是不是自己所期待的;除此之外,class相依的其他class也這樣一路被寫下來。

這樣的順序並沒有什麼問題,但是容易因為method行為非我們預期,或是需要撰寫額外的class而停下來修改,如此往返,容易造成我們思考的中斷。

在TDD裡面所建議的開發方式,則是完全相反;會從組合API開始寫起,例如在下圖的OrderService,

  1. 你想要在裡面使用CreditService,但尚未被撰寫,就先寫CreditService這個 class就好
  2. 再回到OrderService繼續撰寫,你想要呼叫 CreditService的 reserve(),但因為CreditService的reserve()尚未被撰寫,就再跳到CreditService撰寫reserve()
  3. 回到OrderService繼續撰寫,…TicketService class也如同OrderService一樣的方式撰寫

如同一開始說的,先擱置你的團隊適不適合TDD,這個開發方向的改變,是可以讓你的團隊開發時的思緒先專注在組合API的那個點,其他要滿足這個API的其他 class,就是現階段的配角,因而加快你的開發速度。

--

--

Rex Wang

最近看了一些網路技術大神建議,藉由寫部落格來記錄自己的學習歷程,並且可以累積自己的技術能力。於是,繼多年前雜誌技術編輯生涯,我再度展開了屬於自己的技術寫作之旅。