[TDD][Codewars]Number of People in the Bus

Codewars 上隨機挑到的題目:Number of People in the Bus

【題目描述】

[TDD][Codewars]Number of People in the Bus_第1张图片
題目描述

看測試用例比較好懂:

[TDD][Codewars]Number of People in the Bus_第2张图片
test cases

題目解釋:每一個 int[] 都有兩個正整數,第一個代表上車的乘客數,第二個代表下車的乘客數。最後的結果就是車子上還剩多少人。

Step 1: 新增測試用例,只有一個 station
【測試代碼】

[TDD][Codewars]Number of People in the Bus_第3张图片
only 1 station test case

【生產代碼】

[TDD][Codewars]Number of People in the Bus_第4张图片
尚未實作的生產代碼

Step 2: hard-code 回傳 p[0][0] - p[0][1]

【生產代碼】

[TDD][Codewars]Number of People in the Bus_第5张图片
hard-code 計算單一 station

先針對單一個 item hard-code 處理,等等只需要把 index = 0 的部分替換成 for loop 的 i 即可。

【重構測試代碼】擷取方法,將驗證行為封裝到 RemainPassengerShouldBe() 裡。

[TDD][Codewars]Number of People in the Bus_第6张图片
refactor test: extract assertion function

Step 3: 新增測試用例,有兩個 station 的情況

【測試代碼】

[TDD][Codewars]Number of People in the Bus_第7张图片
2 stations test cases

【生產代碼】hard-code,當還有第二個 station 時,累加 remainPassengerCount

[TDD][Codewars]Number of People in the Bus_第8张图片
hard-code: sum the second station passengers

Step 4: 新增測試用例,有三個 station 的情況

【測試代碼】重複了三次類似的處理,逼出生產代碼使用 loop。

[TDD][Codewars]Number of People in the Bus_第9张图片
3 stations test case

【生產代碼】一樣先 hard-code,通過測試用例後,再重構出 for loop。

[TDD][Codewars]Number of People in the Bus_第10张图片
hard-code to handle the third station passengers

【重構】擷取方法,將 remainPassgerCount 的計算抽到 RemainPassengerCountOfCurrentStation() 中,避免同樣的計算重複三份。

[TDD][Codewars]Number of People in the Bus_第11张图片
refactor: extract method

【重構】以 for loop 取代 hard-code 的 [0], [1], [2] index。

[TDD][Codewars]Number of People in the Bus_第12张图片
refactor: loop to replace hard-code index

【通過 Codewars 上所有測試用例】

[TDD][Codewars]Number of People in the Bus_第13张图片
pass all test cases at Codewars

【重構】使用 LINQ 的 Aggregate() 來取代這個 for loop 的行為,讓語意更加清楚。

[TDD][Codewars]Number of People in the Bus_第14张图片
refactor: use Aggregate()

一行搞定這個 Aggregate 的行為!

結論

寫 LeetCode 久了,突然看到這樣的題目,一直在想是不是哪邊有陷阱。結果真的是一題單純到爆炸,單純考會不會寫程式的考題。

但我還是決定用 TDD 一路驅動跟重構出最後版本的代碼,希望可以提供給剛入門的朋友當參考。

GitHub commi history: Codewars_NumberOfPeopleInTheBus


大部分的 LINQ 都是在封裝 foreach loop 的巡覽行為,賦予其更簡單、有彈性、易讀的寫法,這種先寫出 loop 再重構成 LINQ,是學習 LINQ to object 本質很重要的一個脈絡。練久了,你就有火眼金睛,看到那些看似複雜的 foreach loop, 可以對照到是否可以重構成 LINQ 的 API 來表示。

你可能感兴趣的:([TDD][Codewars]Number of People in the Bus)