爲什麼你會有一個抽象基類定義一個只有一個(總是和永遠)派生類的庫的接口?抽象基類沒有多態性
回答
您可能想要換出類似於單元測試的實現
您爲什麼要這樣做的一個原因是可測試性。當依賴對象被定義爲接口時,測試依賴對象就簡單多了。這給了容易模擬或存根的能力。
過去,除非考慮IOC和依賴注入,否則我想不出一個好的理由。這個類可能會在稍後改變它的實現,而不會改變簽名嗎? – hivie7510 2011-06-06 17:51:33
也許這只是我,但是擴展類本身並添加一些方法(或構造函數)爲測試設置私有變量通常更容易(而且更少錯誤)?或者,如果我想添加日誌記錄,我可以輕鬆地覆蓋這些方法,處理日誌記錄並調用超類。沒有這個,你必須兩次實現通用功能,這聽起來像是一個壞主意。 – Voo 2011-06-06 17:53:09
我通常在.NET中工作,所以我更喜歡設置我的嘲笑的期望,然後重播行爲。在C++中,這可能完全不同。 – hivie7510 2011-06-06 17:55:18
如果你可以100%確定總是隻有一個派生類和一個派生類?沒有多少理由。但是:事實上,你幾乎不會100%確定任何東西,當然也不會代碼的未來。
違反reused abstraction principle。
總之,不要這樣做。
那些誰說「測試」俯瞰,你可以只更換
Base < - > Derived
Base < - > DerivedForMockingAndTesting
與
Derived < - > DerivedForMockingAndTesting
也就是說,讓你現有的實現Derived
作爲「抽象」被嘲笑並在單元測試中進行測試。
如果Derived'的構造函數做了一些你不想讓模擬操作的東西? – 2011-06-06 18:09:36
還是有非虛擬功能? – Puppy 2011-06-06 19:57:22
您可能會發現該類的不同版本需要二進制兼容。你也可能會發現,由於其他原因,你希望封裝類的定義 - 例如,因爲定義需要一個包含可憐的宏的頭,那種事情,或包含定義類所需的頭的頭編譯時間很長。
例如,我寫了一個類來封裝我的操作系統提供的功能 - 目前,像動態加載和創建窗口這樣的功能。即使只有一個編譯目標(Windows等)的實現,我選擇使用運行時抽象,因爲我想保證我的代碼的其餘部分從未看到特定於平臺的頭文件,並且Windows頭部充滿了如此多的宏和東西,我不希望它們泄漏出去。
最明顯的原因是能夠將類' 實現放在源文件中,而不是放在標題中。在頭文件中公開的所有 是抽象基類(以及構造它的必要工廠函數 ,但這可能是一個靜態成員)。這個 避免了必須包含任何成員數據的頭文件; pimpl 成語在C++中更習慣於此,但使用抽象類如 這遠不是未知數,並且工作得很好。
- 1. 傑克遜多態性 - 抽象類,沒有財產
- 2. Scala抽象類型和多態性
- 3. 靜態屬性抽象類
- 4. 抽象基類的抽象子類
- 5. quartz.net抽象基類
- 6. 抽象基類QPointer
- 7. 類具有靜態功能進行抽象基類在C++
- 8. 抽象基類或類?
- 9. 如果沒有抽象成員,基類應該標記爲抽象嗎?
- 10. 抽象參考成員的多態性
- 11. 抽象類與抽象字段和子類化沒有鑄造
- 12. 模板,多態,抽象基類指針和運行時鑄造
- 13. 多態性基類指針
- 14. 抽象類和多態使用數組
- 15. 如何在使用抽象類的java中使用多態性?
- 16. 的Java多態性/抽象類的幫助
- 17. C++中的多態性和類抽象示例
- 18. 員工繼承,多態性和抽象類
- 19. Haskell中的抽象數據類型與參數化多態性
- 20. 抽象基類實現
- 21. 抽象基類定義
- 22. @classmethod與抽象基類
- 23. 如何從抽象基類
- 24. C++/CLI抽象基類?
- 25. 抽象基類益智
- 26. C++使用抽象基類
- 27. LinqToSql和抽象基類
- 28. Autofac解決抽象基類
- 29. RhinoMocks和抽象基類
- 30. Django管理沒有表現出抽象基類領域
你是說我在哪裏有類Foo的東西:公共基地和類FooTest:公共基地,我會實例化FooTest在單元測試程序,可能具有樁功能? – Ternary 2011-06-06 17:58:06
是的,或者使用像googlemock這樣的模擬框架來爲你做 – Rich 2011-06-06 18:01:31
你可以通過擴展使用的類(這也意味着你可以重用已經存在的功能)而無需特殊的接口。 – Voo 2011-06-06 18:12:32