在我見過的所有MVC項目中,「服務」和「DAO」類總是實現它們自己的接口。但幾乎所有的時候,我都沒有看到過這種界面有用的情況。服務和DAO總是實現接口
在這些情況下是否有任何理由使用接口?在「服務」和「DAO」類中不使用接口可能會導致什麼結果?我無法想象任何後果。
在我見過的所有MVC項目中,「服務」和「DAO」類總是實現它們自己的接口。但幾乎所有的時候,我都沒有看到過這種界面有用的情況。服務和DAO總是實現接口
在這些情況下是否有任何理由使用接口?在「服務」和「DAO」類中不使用接口可能會導致什麼結果?我無法想象任何後果。
基於接口的實現有助於在測試套件中模擬它們。在我們的項目中,在測試服務層時,我們模擬DAO並提供硬編碼數據,而不是真正連接到數據庫。同樣的理由也適用於服務層。
Spring是一個Inversion of Control容器。這在某種意義上意味着您使用的類的實現不在應用程序上,而在於其配置。如果您有需要UserRepository
存儲User
實例的類,它會是這樣的
class UserService {
@Autowired
private UserRepository userRepository;
}
interface UserRepository {
List<User> getUsers();
User findUserBySIN(String SIN);
List<User> getUsersInCountry(Long couyntryId);
}
而你也有一顆豆宣佈它
<bean class="com.myapp.UserRepositoryHibernateImpl">
...
</bean>
注意這個bean是UserRepositoryHibernateImpl
這將實施UserRepository
。
在世界未來的某個時候,Hibernate項目將不再受支持,您確實需要一個僅在Mybatis上可用的功能,因此您需要更改實現。因爲您的UserService
類正在使用通過接口類型聲明的UserRepository
,所以只有接口上可見的方法對類可見。因此,更改userRepository
的實際多態類型不會影響其餘客戶端代碼。您需要更改的所有內容(不包括創建新類)是
<bean class="com.myapp.future.UserRepositoryMyBatisImpl">
...
</bean>
並且您的應用程序仍然有效。
但是,如果您要從「UserRepositoryHibernateImpl」切換到UserRepositoryMybatisImpl,那麼您將不得不編寫大量代碼。所以你一定會重建你的應用程序。爲什麼要改變一行Java('userRepository'的變量聲明)比改變一行XML(bean聲明)更不吸引人?這實際上不是傾向於接口的論點。 –
'UserRepositoryHibernateImpl'和'UserRepositoryMybatisImpl'都實現了一些'UserRepository'接口。所有交互都通過該接口完成。所以切換背後的東西是非常容易的。客戶不會改變。如果它們是通過與實現的特定交互完成的,那麼您將不得不更改與其交互的代碼。有了接口,你不需要。而對於Spring,你可以在上下文中用一個簡單的聲明來指定實現。 –
是的,我明白這一切。我只是不買進炒作。 –
有許多支持接口的論據,請參閱Google。
我能加入到所說的幾點別人:
總之,它只是有良好的接口!
儘早使用接口使您的應用程序可擴展,並且不使用它的結果是犧牲了應用程序的可伸縮性。
我一直在問自己最近有一個完全相同的問題,即使我知道將會有一個實現類,創建一個接口也是愚蠢的,並且增加了膨脹(每個Java程序員試圖更實用語言會知道這種感覺)。這是另一個彙編模塊,通常只是爲了滿足一個內心的教條主義者而創建的。
Spring似乎已經發展成爲一種面向模塊/組件的框架,其中程序員只創建塊並且框架將它們組裝在一起。這就是爲什麼擁有多個符合條件的bean是一個問題並且使事情複雜化(最終你會使用限定符來殺死DI的目的)。程序員自然會嘗試避免類型歧義,以最大限度地減少所需配置的數量,理想情況下使任何給定的塊僅適合一個「插槽」。
在我看來,DI最大的優點不是,它可以很容易地(通過簡單的XML配置改變類聲明的類型)改變的實現,但它允許依賴關係更容易分離,從而更容易測試每個組件的分離。你不需要獨子接口。
由於逆向工程類提取其接口將是一個純粹的機械任務,我不會擔心「如果我需要添加另一個實現呢?」論據。
免責聲明:中小型應用程序開發人員的意見;我確定情況會隨着大型項目而改變。
但是有一些模擬框架可以像模擬界面一樣輕鬆地模擬類。我不認爲這是分離接口的一個參數。 –