我沒有講所有有關IOC / DI的理論,而是想舉例說明。
要求:我們將獲得一些客戶地址,并且需要驗證該地址。
經過一番評估,我們考慮使用Google地址驗證服務。
傳統(不良)方法:
只需創建一個AddressVerificationService類并實現邏輯即可。
假設GoogleAddressVerificationService是Google提供的一項服務,該服務將Address作為字符串并返回經度/緯度。
class AddressVerificationService
{public String validateAddress(String address){GoogleAddressVerificationService gavs = new GoogleAddressVerificationService();String result = gavs.validateAddress(address); return result;}
}
這種方法的問題:
1.如果要更改地址驗證服務提供商,則需要更改邏輯。
2.您不能使用某些虛擬AddressVerificationService進行單元測試(使用模擬對象)
由于某些原因,客戶要求我們支持多個AddressVerificationService Providers,因此我們需要確定在運行時使用哪種服務。
為了適應這一點,您可能會想到更改以下類:
class AddressVerificationService
{
//This method validates the given address and return longitude/latitude details.public String validateAddress(String address){String result = null;int serviceCode = 2; // read this code value from a config fileif(serviceCode == 1){GoogleAddressVerificationService googleAVS = new GoogleAddressVerificationService();result = googleAVS.validateAddress(address);} else if(serviceCode == 2){YahooAddressVerificationService yahooAVS = new YahooAddressVerificationService();result = yahooAVS.validateAddress(address);}return result;}
}
這種方法的問題:
?
1.每當您需要支持新的服務提供商時,都需要使用if-else-if添加/更改邏輯。 2.您不能使用某些虛擬AddressVerificationService進行單元測試(使用模擬對象)
IOC / DI方法:
在上述方法中,AddressVerificationService負責控制其依賴項的創建。
因此,只要其依賴項發生更改,AddressVerificationService就會更改。
現在,讓我們使用IOC / DI模式重寫AddressVerificationService。
class AddressVerificationService{private AddressVerificationServiceProvider serviceProvider;public AddressVerificationService(AddressVerificationServiceProvider serviceProvider) {this.serviceProvider = serviceProvider;}public String validateAddress(String address){return this.serviceProvider.validateAddress(address);}}interface AddressVerificationServiceProvider{public String validateAddress(String address);}
在這里,我們注入了AddressVerificationService依賴項AddressVerificationServiceProvider。
現在,讓我們使用多個提供程序服務來實現AddressVerificationServiceProvider。
class YahooAVS implements AddressVerificationServiceProvider{@Overridepublic String validateAddress(String address) {System.out.println("Verifying address using YAHOO AddressVerificationService");return yahooAVSAPI.validate(address);} }class GoogleAVS implements AddressVerificationServiceProvider{@Overridepublic String validateAddress(String address) {System.out.println("Verifying address using Google AddressVerificationService");return googleAVSAPI.validate(address);}}
現在,客戶可以選擇使用哪個服務提供商的服務,如下所示:
AddressVerificationService verificationService = null;AddressVerificationServiceProvider provider = null;provider = new YahooAVS();//to use YAHOO AVSprovider = new GoogleAVS();//to use Google AVSverificationService = new AddressVerificationService(provider);String lnl = verificationService.validateAddress("HitechCity, Hyderabad");System.out.println(lnl);
對于單元測試,我們可以實現一個Mock AddressVerificationServiceProvider。
class MockAVS implements AddressVerificationServiceProvider{@Overridepublic String validateAddress(String address) {System.out.println("Verifying address using MOCK AddressVerificationService");return "<response><longitude>123</longitude><latitude>4567</latitude>";}}AddressVerificationServiceProvider provider = null;provider = new MockAVS();//to use MOCK AVS AddressVerificationServiceIOC verificationService = new AddressVerificationServiceIOC(provider);String lnl = verificationService.validateAddress("Somajiguda, Hyderabad");System.out.println(lnl);
通過這種方法,我們可以解決上述基于非IOC / DI的方法的問題。
1.我們可以根據需要提供盡可能多的商品。 只需實現AddressVerificationServiceProvider并將其注入即可。 2.我們可以使用模擬實現使用虛擬數據進行單元測試。
因此,通過遵循“依賴注入”原理,我們可以創建基于接口的松散耦合且易于測試的服務。
參考: 我是如何通過JCG合作伙伴 Siva Reddy在“ 我的技術實驗”博客上 向我的團隊解釋依賴注入的 。
翻譯自: https://www.javacodegeeks.com/2012/06/how-i-explained-dependency-injection-to.html