天天看点

DI依赖注入设计模式

​​《DIP依赖反转原则——实现松耦合的设计》​​ 我们通过创建和使用抽象实现了DIP原则,进一步获得松耦合设计。本单将使用依整注入(DI)设计模式来将依赖的对象的创建彻底移出类外面去,以获得完全的松耦合的程序设计。

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);
    }
}      

继续阅读