例如:s 為 "cwAT", 期望回傳值為 "C-Ww-Aaa-Tttt"
【新增測試代碼】s_is_b_should_return_B()

ToUpper() 轉大寫後回傳【生產代碼】

【重構測試代碼】封裝 assertion 行為,AccumShouldBe()

【測試代碼】

s[0] 與 s[1] 轉大寫與連接號串接【生產代碼】

【重構生產代碼】將 char 呼叫 ToString() 與 ToUpper() 重構,擷取方法至 ToUpperChar()

【新增測試代碼】

【調整生產代碼】增加 ToLower() 處理,以通過測試案例

【重構生產代碼】重構擷取方法,將 char 轉成小寫也封裝成 ToLowerChar()

【新增測試代碼】

【調整生產代碼】hard-code 處理 s[2] 的部分,等等再來重構商業邏輯

【重構生產代碼】使用 GetRepeatLetters() 取代原本 hard-code 的重複字母

【重構生產代碼】使用 Loop  取代 s[0], s[1], s[2] hard-code index

【重構生產代碼】以 LINQ 的 Aggregate() 取代 for loop 不斷串接 result 的邏輯。

【重構生產代碼】將每個 char 透過 Select() 轉成對應的重複字串,再用連接號連接每個 element

    public class Accumul
    {
        public static String Accum(string s)
        {
            var result = s.Select((c, i) => ToUpperChar(c) + GetRepeatLetters(c, i));
            return string.Join("-", result);
        }
        private static string GetRepeatLetters(char letter, int repeatTimes)
        {
            return string.Concat(Enumerable.Repeat(letter.ToString().ToLower(), repeatTimes));
        }
        private static string ToUpperChar(char letter)
        {
            return letter.ToString().ToUpper();
        }
    }
結論
同樣的題目,練習不只一次,有時思路會很不一樣。這一題 Codewars 一開始其實是三個人以 TDD 一起做 coding dojo 的過程,我們最後一起完成了這一題,但我當天晚上重新練習了一次,讓整個過程更貼近精簡的 TDD 堆砌出生產代碼。
附上兩個版本的 commit history 供各位朋友參考:
生產代碼的主邏輯最後其實可以一行代碼就搞定,但 TDD 延展出來的思路還是本文練習的重點,而且可以看到每一行都是其來有自,為了滿足某個需求而驅動出來的代碼。
blog 與課程更新內容,請前往新站位置:http://tdd.best/

