有人說“TDD(測試驅動開發(fā))可以帶來優(yōu)秀的設計”,也有人說“TDD會對設計有負面影響”。如果有個具體例子的話,討論起來會實際得多,所以下面我們來看一下私有方法以及它與優(yōu)秀設計、可測試性的關系——這種對立觀點的一個實例。 Szczepan Faber在博客中寫道,私有方法是一種反模式: 自從TDD誕生之日起,私有方法似乎就有了壞味道。被測試浸染的開發(fā)者總想尋找測試私有方法的辦法。嗯……這顯然是很困難的,所以問題就從“如何”變成了“為何”:為何要測試私有方法?大多數(shù)TDDers都會立刻回答說:別這么干。于是TDD又改變了我們構建軟件的方式,對私有方法進行了重新評估 Jay Fields在博客上描述了在ruby中測試私有方法的一種通用方式: ……我很少測試私有方法。我更傾向于通過public API來進行測試。不過偶爾也有這種時候,如果你可以給一兩個私有方法寫點測試用例的話,日子就可以過的容易一些。 Michael Feathers在去年的The Deep Synergy Between Testability and Good Design一文中指出,TDD可以帶來優(yōu)秀的設計,而反過來想,那些不可測試的代碼應該引起我們的深思: 在我編寫測試時,如果覺得有強烈的沖動促使我去測試一個私有方法,我就會把它看作一種暗示。它告訴我,我的類已經被封裝得趨近于封閉了,測試代碼無法再通過公共接口來“理解”這個類的行為。我順從了這個暗示的召喚,重新構建了代碼。通常我都會把這個私有方法(可能還有一些相關的方法)挪到一個新的類里面,在那里它不再是私有,可以讓測試代碼訪問。
以上種種想法,都傾向于不鼓勵使用私有方法,在天平的可測試性一端加入更多砝碼。但它們并不是唯一的聲音。實際上在我們所能看到的有關面向對象開發(fā)的觀點中,很多都是支持少用一些類,極盡所能使用封裝。在public API中只暴露最小的API集合,就會將耦合降低到最小。David West在Object Thinking一書中,引用了Lorenz和Kidd在Object Oriented Software Metrics書中的論述:
一個應用程序應該最多包括40個故事,100個類。 應用程序所屬的整個業(yè)務領域不應該需要超過1000個類來完成。 每一次迭代后都該扔掉25-30%的代碼。 每個類的職責:平均是7個。 每個類的方法數(shù):平均是12個。 每個方法的代碼行數(shù):平均是15個。 需要進行注釋的代碼行數(shù)百分比:60。 case語句的數(shù)量:平均為0。 如果私有方法確實是壞味道,需要把它們挪到自己所應歸屬的類中,這不就是“為了讓測試變得簡單,而增加類的數(shù)量”么?它勢必會造成類的數(shù)量急劇膨脹。
那么該拿私有方法怎么辦呢?測試它們太折磨人了。我們可否修改一下,把它們暴露給測試代碼?或者不去測試私有方法,讓設計與可測試性永不相干?或者,私有方法是一種壞味道,它表明一個類做了太多事情?
|