谈谈我对DI的理解

本文中DI指依赖倒置

依赖的概念

Baidu百科:依靠别人或事物而不能自立或自给。

软件开发中的依赖:依赖描述了两个模型元素之间的关系,如果被依赖的模型元素发生变化就会影响到另一个模型元素。

DI的概念

A. 上层模块不应该依赖于下层模块,它们共同依赖于一个抽象。
B. 抽象不能依赖于具象,具象依赖于抽象。

实例谈开

在分层开发中,通常会有这样的两个模块:DAL(数据访问层)和BLL(业务逻辑层) 。 下面就以电子商务系统中的 订单、产品、用户 为例来说说这两个模块之间的依赖关系。

正向依赖

DAL:

<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->public class OrderDao
{
public List < Orders > GetOrderByUserID( int userid)
{
throw new NotImplementedException();
}
public List < Orders > GetOrderByProductID( int productID)
{
throw new NotImplementedException();
}
}

BLL:

<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->public class Order
{
private OrderDaoorderDao; // 对DAL中OrderDao的引用
public Order(OrderDaoorderDao)
{
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)都应当依赖于抽象。那么我们引入一个抽象模块。

抽象模块:

<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->public interface IOrderDao
{
List
< Orders > GetOrderByUserID( int userid);

List
< Orders > GetOrderByProductID( int productID);
}

DAL:

<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->public class OrderDao:IOrderDao// 继承于抽象
{
public List < Orders > GetOrderByUserID( int userid)
{
throw new NotImplementedException();
}
public List < Orders > GetOrderByProductID( int productID)
{
throw new NotImplementedException();
}
}

BLL:

<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->public class Order
{
private IOrderDaoorderDao; // 依赖于抽象
public Order(IOrderDaoorderdao)
{
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):对于扩展开放,对于更改封闭。

于是有了下面的设计。

抽象模块:

<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->public interface IOrderUserDao
{
List
< Orders > GetOrderByUserID( int userid);
}
public interface IOrderProductDao
{
List
< Orders > GetOrderByProductID( int productID);
}

DAL:

<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->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:

<!-- <br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->public class User
{
private IOrderUserDaoorderDao; // 依赖于抽象
public User(IOrderUserDaoorderdao)
{
orderDao
= orderdao;
}
public List < Orders > GetOrderByUserID( int userid)
{
List
< Orders > list = null ;
list
= orderDao.GetOrderByUserID(userid);
return list;
}
}

public class Product
{
private IOrderProductDaoorderDao; // 依赖于抽象
public Product(IOrderProductDaoorderdao)
{
orderDao
= orderdao;
}
public List < Orders > GetOrderByProductID( int productID)
{
List
< Orders > list = null ;
list
= orderDao.GetOrderByProductID(productID);
return list;
}
}

那么您的意见呢?


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值