簡體   English   中英

服務和DAO始終實現接口

[英]Service and DAO always implement interfaces

在我看到的所有MVC項目中,“服務”和“ 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

<bean class="com.myapp.UserRepositoryHibernateImpl">
   ...
</bean>

注意,這個bean是UserRepositoryHibernateImpl ,它將實現UserRepository

在將來的某個時候,Hibernate項目將不再受支持,您確實需要僅在Mybatis上可用的功能,因此您需要更改實現。 因為您的UserService類正在使用用接口類型聲明的UserRepository ,所以該類僅可見接口上可見的方法。 因此,更改userRepository的實際多態類型不會影響其余的客戶端代碼。 您需要更改的所有內容(不包括創建新類)是

<bean class="com.myapp.future.UserRepositoryMyBatisImpl">
   ...
</bean>

並且您的應用程序仍然有效。

有很多支持接口的論點,請參見Google。

我可以補充其他人提到的幾點:

  1. 想象一下,您將DAO實現從Hibernate更改為iBatis。 依賴接口而不是實現將對服務層有很大幫助。
  2. 如果您使用AOP或使用JDK動態代理的代理,則您的類必須實現接口。 CGLIB並非如此。
  3. 在服務層中,如果您希望將方法釋放給其他客戶端以進行調用,那么給它們“作為契約的接口”將比實現更有意義。
  4. 如果您要從daos.jar分離services.jar,則在daos上具有接口可以避免在daos.jar發生更改時重新編譯services.jar。

簡而言之,擁有接口就很好!

基於接口的實現有助於在測試套件中模擬它們。 在我們的項目中,測試服務層時,我們模擬DAO並提供硬編碼數據,而不是真正連接到DB。 同樣的論點也適用於服務層。

盡早使用接口可以使您的應用程序具有可伸縮性,並且不使用接口的后果就是犧牲了應用程序的可伸縮性。

我最近一直在問自己一個完全相同的問題,覺得即使我知道將永遠只有一個實現類,創建一個接口也是很愚蠢的,並且使人adds腫(每個嘗試使用更實用的語言的Java程序員都會知道這個問題)。感覺)。 那是另一個編譯模塊,通常只是為了滿足一個人的內心教條主義者而創建的。

Spring似乎已經發展成為面向模塊/組件的框架,程序員只在其中創建塊,然后框架將它們組裝在一起。 這就是為什么要有多個與條件匹配的bean成為一個問題,並使事情變得復雜的原因(最終使用限定符會破壞DI的目的)。 程序員自然會嘗試避免類型歧義,以最大程度地減少所需配置的數量,理想情況下,使任何給定的塊僅適合一個“插槽”。

在我看來,DI的最大優點不是 (通過簡單地更改config XML中聲明的類的類型)使實現的更改變得容易,而是使依賴關系的分離更加容易,從而使每個組件的分離測試更加容易。 。 您不需要一個孩子的接口。

由於對類進行逆向工程以提取其接口將是純粹的機械任務,因此我不必擔心“如果我需要添加另一個實現會怎樣?” 論點。

免責聲明 :中小型應用程序開發人員的意見; 我相信大型項目的情況會有所變化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM