昨天寫的〈測試驅動開發要徹底重構〉,曾經提到 Steven 說到「如果像閣下文中說:『系統不斷演進及需求不斷改變之下,也可能會使架構或設計愈來愈複雜而變得難以維護』,我則認為是在進行 TDD 時候沒有徹底去重構系統。」,同人認為這段話有根本上的邏輯的繆誤,於是回應:
假如上面的話是成立的,那麼代表只要徹底重構系統就不會造成「系統不斷演進及需求不斷改變之下,也可能會使架構或設計愈來愈複雜而變得難以維護」嗎?如果是這樣,那 XP 根本就不需要 Refactoring 這個實務來改善程式的結構,因為你都徹底重構程式,程式結構變差的情況是根本不可能發生。
而且依照本人 20 年來軟體開發的經驗,我還不沒有看到有程式一開始就寫得很好,到後來可以不用改變架構而符合新需求的。倒是隨著對問題的更清楚,或是程式需求的變化,讓程式必須重構的現象時常履見不鮮!
所以如果自以為自己博覽群書,很懂得TDD的實務。也不要忘了用心思考,以免自己對TDD的最佳實務的認知,不小心犯了根本上的邏輯繆誤?
結果,後來同人在 Facebook 的 Scrum community in Taiwan 看到 Steven 做了以下的回應:
先說件簡單易明的事情,其實我很不喜歡閣下把 TDD 放到 『精神』 層次,卻忘記了基本步驟。
之前的討論根本連事實層次都被忽略,根本談不上是什麼多少年的經驗或者如何用心思考,連 TDD 的最基本步驟也忘記,TDD 的基本步,不是閣下做多少年工作就可以把人家的定義去改變的,我也不明白為何有 20 年工作經驗就可以把 『Refactoring』 說成 『並不必然是 TDD 的必要的步驟』,這不是邏輯問題,更不是有過什麼開發經驗然後用心思考就可以改變的事情,這是就算對軟體開發的認知不夠閣下那麼 『全面』 的都能看出的謬誤,如果閣下這樣就認為是因為說不過閣下就建議多看書本,本人深表遺憾。
我是來討論問題的,我沒有興趣去傷害閣下感情,好好閱讀書本,只是反映 TDD 三個步驟是什麼根本不存在爭議,更沒有 『好好閱讀什麼書或文章才能跟我討論』 的意思,我還未自大得要別人看過多少書才可以討論問題,亦正如討論問題我也不用跟別人說我有多少年工作經驗一樣,而且本人是衷心認為多讀書是有益的(不管是閣下還是什麼人),多讀書亦不是為上來辯論的,不過閣下如果感到有所不悅的,我就先行道歉,還是希望冷靜一點討論問題。
而簡單的例子也是思辦的過程的一部份,一方面是簡單易明地討論問題,另一方面是如果連簡單的例子也說不通,又怎麼能去談更複雜的問題呢?
上面提到:』那XP根本就不需要 refactoring 這個實務來改善程式的結構,因為你都徹底重構程式,程式結構變差的情況是根本不可能發生。』
不如冷靜一點再讀讀這句子,』XP 不需要 Refactoring 是因為徹式地進行 Refactoring』,我就看不明白這是什麼邏輯,一邊說不需要,另一邊說徹底地進行。
這裡的問題是軟件是會改變的,可能是新增功能,也可能發現有其他問題,每次帶來的變更其實都需要進行重構的。所以說 XP 不需要 Refactoring 也不正確。
世上的確沒有一寫就好的代碼,而且世界是會變的,Refactoring 就是避免以後的更改越來越困難。把 『徹底地進行重構』 理解成 『XP 不需要重構這實踐』 完全沒有邏輯可言。
我也沒有反對不用改變程式架構就能滿足新需求,亦沒有否定 Refactoring 的重要性,只不過我還是建議新的功能以 TDD 方式進行開發,有測試、有代碼、然後進行重構的。
在足夠測試覆蓋下進行重構是可使系統在不斷演進及需求不斷改變之下,使架構或設計仍然處於可以維護的狀態,相反我指出的是,如果程式架構和設計越來越難維護,是重構的力度不足夠。
前面還提到:』但重構的目的為何?就重構的定義在不改變功能的情況下改善程式結構,以增加程式碼的彈性以利未來增加或改變功能。因此如同那第三步所言,為了去掉重覆性而重構。』
如果重構只是為了去掉重覆性,那 TDD 的第三步不如叫 『Remove Duplication』 好了,無可否認代碼重覆是很常見的問題,但把這裡的重構限制成消除代碼其實會局限系統的將來發展,而且到了 TDD 的第三步,系統是應該有足夠的測試去覆蓋系統,重構的力度沒理由只局限於新增功能和現有程式的重覆。
我就相信閣下是 Refactoring 的專家,也應該會知道一些 Refactoring 的模式是完全相反的,例如 『Pull Up Method』 和 『Push Down Method』,更是需要觀察當時的情況來作決定,而沒有一面倒那個才是好的模式,我實在不明白為何要把 TDD 的 Refactoring 局限到只做 『去掉重覆性』。
這是實務上會發生的事情,消除代碼重覆以外的重構還是會發生的,如果只是單單只是 『消除重覆』,這會是另一個我認為進行重構不夠徹底的事情。
上面已經不單單是用心思考,而是由理論到實踐都可以看得到的事情。
跟討論 Refactoring 和 TDD 觀點以外的聲音,就引用 Chet Henderickson 的說法,全部都是我錯好了,現在可以解決問題嗎?
看了 Steven 的回應,同人當下的反應是不想浪費時間與心力與他周旋下去,但後來想到或許是因為 1/9 敏捷開發分享會我要分享實施 XP 的經驗與心得,也許這是一個巧妙的同步事件。我可以趁這個機會,導正對 XP 或是 Agile 的一些錯誤觀念。
例如敏捷開發並不是教條式的照本宣科,開發者要懂得變通最重要的是用心思考,而非把必要的思考都看成精神層面的問題,這並非適用於敏捷開發的心智模式。以下是同人在 Facebook 的 Scrum community in Taiwan 的回應,但一些詞句有略為做過一番修飾,以清楚表達我對測試驅動開發步驟的看法。 Read the rest of this entry »