谈谈我对DI的理解
本文中DI指依賴倒置。
依賴的概念
Baidu百科:依靠別人或事物而不能自立或自給。
軟件開發中的依賴:依賴描述了兩個模型元素之間的關系,如果被依賴的模型元素發生變化就會影響到另一個模型元素。
DI的概念
A. 上層模塊不應該依賴于下層模塊,它們共同依賴于一個抽象。
B. 抽象不能依賴于具象,具象依賴于抽象。
實例談開
在分層開發中,通常會有這樣的兩個模塊:DAL(數據訪問層)和BLL(業務邏輯層) 。 下面就以電子商務系統中的 訂單、產品、用戶 為例來說說這兩個模塊之間的依賴關系。
正向依賴
DAL:
public class OrderDao
{
??? public List<Orders> GetOrderByUserID(int userid)
??? {
??????? throw new NotImplementedException();
??? }
??? public List<Orders> GetOrderByProductID(int productID)
??? {
??????? throw new NotImplementedException();
??? }
}
BLL:
public class Order
{
??? private OrderDao orderDao;//對DAL中OrderDao的引用
??? public Order(OrderDao orderDao)
??? {
??????? orderDao = orderDao;
??? }
??? public List<Orders> GetOrderByUserID(int userid)
??? {
??????? List<Orders> list = null;
??????? list = orderDao.GetOrderByUserID(userid);
??????? return list;
??? }
??? public List<Orders> GetOrderByProductID(int productID)
??? {
??????? List<Orders> list = null;
??????? list = orderDao.GetOrderByProductID(productID);
??????? return list;
??? }
}
?BLL中Order持有了DAL中OrderDao的引用,這個時候BLL模塊依賴于DAL模塊。他們之間構成了緊耦合。如果要更換DAL模塊,顯然需要修改BLL中的代碼。
引入抽象
依賴倒置的思想告訴我們上層模塊(BLL)和下層模塊(DAL)都應當依賴于抽象。那么我們引入一個抽象模塊。
抽象模塊:
public interface IOrderDao
{
??? List<Orders> GetOrderByUserID(int userid);
??? List<Orders> GetOrderByProductID(int productID);
}
DAL:
public class OrderDao : IOrderDao//繼承于抽象
{
??? public List<Orders> GetOrderByUserID(int userid)
??? {
??????? throw new NotImplementedException();
??? }
??? public List<Orders> GetOrderByProductID(int productID)
??? {
??????? throw new NotImplementedException();
??? }
}
BLL:
public class Order
{
??? private IOrderDao orderDao;//依賴于抽象
??? public Order(IOrderDao orderdao)
??? {
??????? orderDao = orderdao;
??? }
??? public List<Orders> GetOrderByUserID(int userid)
??? {
??????? List<Orders> list = null;
??????? list = orderDao.GetOrderByUserID(userid);
??????? return list;
??? }
??? public List<Orders> GetOrderByProductID(int productID)
??? {
??????? List<Orders> list = null;
??????? list = orderDao.GetOrderByProductID(productID);
??????? return list;
??? }
}
現在BLL持有了對抽象模塊的引用,而DAL也依賴于該抽象模塊。抽象模塊的引入消除了BLL和DAL之間的依賴。那么這種方法是否完美呢?
接口的單一性
在一個業務驅動的系統中,如果與訂單相關的業務發生變化,會導致我們去修改 IOrderDao,相應的DAL中的OrderDao 和BLL的Order都會被修改。
什么原因呢?
上面的這種設計讓我們無法保持一個穩定的接口。面向對象設計中,有這樣的兩個原則:
單一職責原則(SRP):保證對象的細粒度和單一性。
開放-封閉原則(OCP):對于擴展開放,對于更改封閉。
于是有了下面的設計。
抽象模塊:
public interface IOrderUserDao
{
??? List<Orders> GetOrderByUserID(int userid);
}
public interface IOrderProductDao
{
??? List<Orders> GetOrderByProductID(int productID);
}
DAL:
public partial class OrderDao : IOrderUserDao
{
??? public List<Orders> GetOrderByUserID(int userid)
??? {
??????? throw new NotImplementedException();
??? }
}
public partial class OrderDao : IOrderProductDao
{
??? public List<Orders> GetOrderByProductID(int productID)
??? {
??????? throw new NotImplementedException();
??? }
}
BLL:
public class User
{
??? private IOrderUserDao orderDao;//依賴于抽象
??? public User(IOrderUserDao orderdao)
??? {
??????? orderDao = orderdao;
??? }
??? public List<Orders> GetOrderByUserID(int userid)
??? {
??????? List<Orders> list = null;
??????? list = orderDao.GetOrderByUserID(userid);
??????? return list;
??? }
}
public class Product
{
??? private IOrderProductDao orderDao;//依賴于抽象
??? public Product(IOrderProductDao orderdao)
??? {
??????? orderDao = orderdao;
??? }
??? public List<Orders> GetOrderByProductID(int productID)
??? {
??????? List<Orders> list = null;
??????? list = orderDao.GetOrderByProductID(productID);
??????? return list;
??? }
}
那么您的意見呢?
作者:青羽
總結
- 上一篇: IIR+全通滤波器级联实现系统零相位相移
- 下一篇: 研究生第一篇学术论文常犯问题总结【喻海良