我没有讲所有有关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 file
if(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
{
@Override
public String validateAddress(String address) {
System.out.println("Verifying address using YAHOO AddressVerificationService");
return yahooAVSAPI.validate(address);
}
}
class GoogleAVS implements AddressVerificationServiceProvider
{
@Override
public 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 AVS
provider = new GoogleAVS();//to use Google AVS
verificationService = new AddressVerificationService(provider);
String lnl = verificationService.validateAddress("HitechCity, Hyderabad");
System.out.println(lnl);
对于单元测试,我们可以实现一个Mock AddressVerificationServiceProvider。
class MockAVS implements AddressVerificationServiceProvider
{
@Override
public 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