大部分企业应用开发和互联网项目的开发都在应用IOC框架。
但是大部分时候,我们也就是这么用用,很少人有去考虑用的到底对不对,合适不合适。
大家都知道依赖倒置原则,这里给出定义:
高层模块不能依赖于底层模块,两者都应该依赖于抽象。
是不是有点颠覆三观!! 难道业务层不应该依赖数据访问层吗。难道是数据访问层依赖业务层吗?
下面是一个最常见的设计,业务层依赖 数据访问层,远程调用,文件访问,log模块等等:
这种设计被称之为 Naive Design。 一旦业务层依赖的任何一个模块发生变化,都会影响到业务层。变化通常是引入错误的原因。
那么我们以依赖倒置的原则来重新设计,得到下图中的结构:
这样是不是业务层就非常独立了。
但是,是不是有点晕了。这是怎么做到的呢? 来看一段简单的示例:
namespace Business { public class OrderService { private readonly IOrderRepository _orderRepository; public OrderService(IOrderRepository orderRepository) { _orderRepository = orderRepository; } public Void CreateOrder() { var order = new Order(); _orderRepository.SaveOrder(order); } } }
这段代码表示创建订单时,调用数据访问层把order对象持久化。
再来看一下项目结构:
可以看到 Business 没有依赖任何工程,DataAccess依赖了Business,Client也就是OrderService的调用方,同时依赖了Business和DataAccess。
你可能已经注意到了, IOrderRepository的接口定义在Business中,而在DataAccess中实现了这个接口。这样就实现了依赖倒置。这样做有什么好处呢,因为IOrderRepository接口的使用是Business提出来的,它只需要知道我要使用这个接口,而不用关心实现,这样就把实现的变化封装在了DataAccess中。这也体现了OO设计中最重要的两个原则:封装变化,面向接口编程。
在使用OrderService的地方,也就是client中,我们创建一个OrderRepository,并作为OrderService的参数传入。代码如下:
static void Main(string[] args) { var orderRepository = new OrderRepository(); var orderService = new OrderService(orderRepository); }
为什么不让OrderService自己创建OrderRepository呢?这样明显会导致双向依赖么。
每次创建OrderService的时候都要new一下OrderRepository,烦不烦。于是就有了IOC框架,帮我们自动创建一个OrderRepository,并注入OrderService。
回头再想想,如果你的项目是正向依赖关系。用IOC框架有意义么? 达到解耦的目的了么?