2009-06-16

我對 Strong Typing vs. Strong Testing 這篇文章的意見



今天下午在看這本書,裡頭有篇文章,看完之後,在噗浪上面寫了一句話,覺得這篇文章的說法似是而非(意思就是說,這文章看來有道理,事實上卻說不太通)。

下班的途中在捷運上又想了想,就把感想寫在這裡(噗浪還是不適合回長文啊)

文章裡說得對的地方:
If it's not tested, it's broken. 這是符合現代程式開發的普遍說法,根據我的經驗,這點我同意。

我覺得有問題的說法:
Python會在程式執行時才發現型別問題,然後丟出實行期錯誤,這個機制看來有問題,但是 Python 還是獲得巨大的成功,所以,執行時期才做型別檢查沒啥問題,只要靠完整的 unit test 就好。
我的回應是:如果你有完整的測試,整個程式都沒問題了,執行時期當然不會有問題啊(廢話)。所以,這個問題被轉換成:如何保證你的程式有"足夠"的測試。
千萬不要跟我說,執行時期才做型別檢查這個作法沒有問題。執行時期才檢查型別的不堅固(爛)程式語言一堆,我應該不需要舉例子吧。

再來舉兩個例子:
  1. 假設你有定期完整詳盡的健康檢查與醫療照護,你會因為這樣就放棄運動跟正常作息嗎?
  2. 假設你是七龍珠裡的孫悟空,你會因為會使元氣玉(大絕)就不用龜派氣功嗎?
舉上面兩個怪怪的例子的原因是:要寫文章推廣好的觀念是不錯,但是不能因為要推廣"大絕"就把容易又有效的小絕招放棄吧。所以,文中的這句 Strong testing, not strong typing.
應該可以改成 Strong testing, and strong typing.

根據我的開發經驗,如果可以在開發初期就做對決策,把軟體的品質放進產品裡(利用基本機制帶來的品質保護),這會比事後再做補救措施來得容易&節省資源。

再回來談大絕(就是文中的 adequate unit tests
就像大絕很難練成一樣,要能執行 adequate unit tests,跟團隊的能力/制度有關,不能假設開發團隊都有能力&資源執行夠質足量的 unit test,更不能為了假設有大絕,就放棄簡單易用的小絕招。

最後的補充:
程式的錯誤,一般來說,有語法錯誤跟邏輯錯誤兩種,如果有編譯器可以多幫你一些忙,處理掉一些錯誤,這是好事。軟體開發耗神費力,可以有多些幫助,就該謝天謝地了。

一些背景資料:
這篇文章的作者 Bruce Eckel 很有名啊,就是Thinking in Java的作者。我以前就是看了他的書才去學Python的。
聽說這篇也很有名(沒時間細查)。但在我看來,這篇說理的邏輯不太通(這就是會有這篇的原因),講述測試的重要性也沒有特別令人信服的地方,我實在看不出這篇的重要性在哪裡。

最後的最後:
多測試沒事,沒事多測試

2 則留言:

Hua 提到...

'''如何保證你的程式有"足夠"的測試'''

沒錯, 這是關鍵. 如同你所說的'''程式的錯誤,一般來說,有語法錯誤跟邏輯錯誤兩種''', 要消除所有語法錯誤與邏輯錯誤才算是完成程式設計. 為了保證邏輯的正確下的測試裡, 應該也會在執行期把語法上的錯誤給找出來. (沒執行過的程式碼不能保證是邏輯正確的吧.)
所以才會有"Strong testing, not strong typing"

York 提到...

Bruce Eckel 這篇文章有幾個專有名詞的用法,跟 Computer Science 的習慣用法不一致。

Python 其實是 strong typing 的語言,

Python 是 dynamic and strong typing 的語言
C/C++ 是 static and strong typing

我相信 Bruce Eckel 把 static typing 誤植成 strong typing 。