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