[英]Why cast to an interface instead of casting to a class java?
我遇到了一些在 spring 框架中使用的 java 類。 首先,applicationContext.xml 中有 bean
<bean id="someBean" parent="txProxyTemplate">
<property name="target">
<bean class="path.to.bean.impl.SomeBeanImpl">
...
</bean>
...
</bean>
我有接口ISomeBean
和它的實現SomeBeanImpl
然后,我有另一個使用 ISomeBean 的類。
public class SomeOtherClass {
...
public function doStuff() {
...
ApplicationContext ctx;
SomeBean theBean = (SomeBean) ctx.getBean;
}
}
我想知道為什么我們要轉換到接口而不是轉換到類。
為什么要將SomeOtherClass
綁定到特定實現? 使用該接口,您會獲得松散耦合 - 您可以針對假實現進行測試,或者稍后切換到不同的實現。
這是控制反轉的很大一部分好處 - 您與依賴項的耦合不像直接在類中實例化它們那樣緊密。
這種類型轉換背后的邏輯是為 Spring IOC 和依賴注入提供自由。 使用這種方法的好處之一是類之間的耦合非常松散,
例如,在您的情況下,如果某個晴朗的早晨您決定更改 ISomeBeanImpl 的代碼,則只要功能不更改,您就不需要更改任何其他內容..
看看Spring IOC文檔,思路會更清晰...
使用依賴注入的一大好處是您的類不必知道使用了哪種實現,只需知道它們需要一個實現。 因此,將其轉換為接口是有意義的。
但是,您不應將其與可以或不可以做什么混淆。
您可以轉換為接口以保持您的代碼通用和松散耦合。 一旦你將一個對象轉換為一個具體的類,你就在你的對象和它的合作者之間添加了一個緊密的耦合。 如果協作者的類類型發生變化,那么您的對象的轉換操作可能會中斷 - 導致 ClassCastException。 相反,如果我們使用接口,您可以自由更改協作者的實現類類型,而不必擔心對客戶端的影響。
有它的風格方面 - 松散耦合等等。
更具體地說:如果您正在使用 AOP(Spring 默認為許多內置功能,例如事務支持)和例如 cglib 代理,則實際的 bean 將不是實現類,它將是一個動態創建的代理-班級。 在這種情況下,您的應用程序將因各種類 ClassCast 異常而失敗。 如果您所做的更改在春季無意中激活了代理行為,那么這可能會帶來令人討厭的驚喜。
依賴注入框架有兩個目標:
如果您對 1 或 2 不感興趣,顯然您不需要依賴注入:只需自己創建 bean SombeBeanImpl = new SomeBeanImpl()
。
如果您只對 1 而不是 2 感興趣,您可以將您獲得的 bean 轉換為SomeBeanImpl
,但是您必須始終使用它。 我懷疑有一種方法可以在 Spring 中指定您只有一個實現並且沒有接口,但我不確定。
如果您對 2 感興趣,那么根據定義,您也對 1 感興趣。 實際上,如果您不想明確說明要實例化的具體類,則可以將其委托給控制對象創建的工廠。 這就是依賴注入框架的真正含義,一個復雜的工廠。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.