《DIP依赖反转原则——实现松耦合的设计》 我们通过创建和使用抽象实现了DIP原则,进一步获得松耦合设计。本单将使用依整注入(DI)设计模式来将依赖的对象的创建彻底移出类外面去,以获得完全的松耦合的程序设计。
依整注入是一种设计模式。它实现了IOC反转控制原则。它将依赖的类的创建在类外面实现,再通过注入的方式将创建好的类注入。比如说,A类依赖B类,那么我们先在A类外面,创建好B类,再将其注入到A类中。注入的方式有三种,在讲它们之间,我们规范上各个类的称呼,比如说上面说的A类,我们称其为Client类,B类则为Service类,还有一个是连接它们的类叫注入器类:
- Client类: 依赖service类。
- Service类: 提供服务给Client类。
- Injector类: 将service类注入到Client类。
注入方式有三种:
- 构造函数注入: 注入器类(Injector类)将service类通过Client的构造函数注入到Client类中。
- 属性注入:注入器类(Injector类)将service类通过Client的公共属性注入到Client类中。
- 方法注入:这种方式的注入,需要Client类实现一个接口,它个接口是提供依赖的。注入器类就会使用这个接口将service类注入到Client类。
举个例子:
我们在前面的实现了DIP的例子上继续改:
public interface ICustomerDataAccess
{
string GetCustomerName(int id);
}
public class CustomerDataAccess implements ICustomerDataAccess
{
public CustomerDataAccess() {
}
public string GetCustomerName(int id) {
return "Dummy Customer Name";
}
}
public class DataAccessFactory
{
public static ICustomerDataAccess GetCustomerDataAccessObj()
{
return new CustomerDataAccess();
}
}
public class CustomerBusinessLogic
{
ICustomerDataAccess _custDataAccess;
public CustomerBusinessLogic()
{
_custDataAccess = DataAccessFactory.GetCustomerDataAccessObj();
}
public string GetCustomerName(int id)
{
return _custDataAccess.GetCustomerName(id);
}
}
构造器注入:
// Client类
public class CustomerBusinessLogic
{
ICustomerDataAccess _dataAccess;
public CustomerBusinessLogic(ICustomerDataAccess custDataAccess)
{
_dataAccess = custDataAccess;
}
public CustomerBusinessLogic()
{
_dataAccess = new CustomerDataAccess();
}
public string ProcessCustomerData(int id)
{
return _dataAccess.GetCustomerName(id);
}
}
public interface ICustomerDataAccess
{
string GetCustomerName(int id);
}
// service类
public class CustomerDataAccess implements ICustomerDataAccess
{
public CustomerDataAccess()
{
}
public string GetCustomerName(int id)
{
//get the customer name from the db in real application
return "Dummy Customer Name";
}
}
// 注入器类
public class CustomerService
{
CustomerBusinessLogic _customerBL;
public CustomerService()
{
// 通过构造器注入ICustomerDataAccess的实例
_customerBL = new CustomerBusinessLogic(new CustomerDataAccess());
}
public string GetCustomerName(int id) {
return _customerBL.ProcessCustomerData(id);
}
}
属性注入:
// Client类
public class CustomerBusinessLogic
{
public CustomerBusinessLogic()
{
}
public string GetCustomerName(int id)
{
return DataAccess.GetCustomerName(id);
}
// 属性
public ICustomerDataAccess DataAccess;
}
// 注入器类
public class CustomerService
{
CustomerBusinessLogic _customerBL;
public CustomerService()
{
_customerBL = new CustomerBusinessLogic();
// 通过属性注入
_customerBL.DataAccess = new CustomerDataAccess();
}
public string GetCustomerName(int id) {
return _customerBL.GetCustomerName(id);
}
}
interface IDataAccessDependency
{
void SetDependency(ICustomerDataAccess customerDataAccess);
}
// Client类,实现IDataAccessDependency接口
public class CustomerBusinessLogic implements IDataAccessDependency
{
ICustomerDataAccess _dataAccess;
public CustomerBusinessLogic()
{
}
public string GetCustomerName(int id)
{
return _dataAccess.GetCustomerName(id);
}
public void SetDependency(ICustomerDataAccess customerDataAccess)
{
_dataAccess = customerDataAccess;
}
}
// 注入器类
public class CustomerService
{
CustomerBusinessLogic _customerBL;
public CustomerService()
{
_customerBL = new CustomerBusinessLogic();
// 通过Client的方法注入。
((IDataAccessDependency)_customerBL).SetDependency(new CustomerDataAccess());
}
public string GetCustomerName(int id) {
return _customerBL.GetCustomerName(id);
}
}