定义
见名知义
DI = Dependency Injection = 依赖注入。
见名知义,DI 就是把依赖项注入到对象中。
它是一种编程技巧。使用它,可以编写出松散耦合的代码。
不过,这种解释比较口水话,不够专业。
专业定义
有一本关于DI的英文著作,书名就叫做《Dependency Injection》,书中涵盖了关于DI的所有内容,并且给出了一个关于DI的专业定义。这个专业定义是:DI 是一组软件设计原则和模式。
我们平时所说的面向接口编程,而不是面向实现编程,这一条重要的建议是设计模式的前提,当然也是DI的前提。
DI 涉及到的设计原则,包括里氏替换原则、开闭原则、单一职责原则;
DI 经常用到的设计模式,包括装饰器模式、组合模式、适配器模式和空对象模式。
但是,这个定义太过抽象,不够具体形象。
形象类比
在专业的软件开发问答网站StackOverflow上,有这样一个问题,“如何向一个5岁的孩子解释DI?”。其中最受好评的答案来自一个叫做“约翰·蒙什”的人,他针对一个想象中的5岁的调查员,给出了一个精确的类比。他是这样说的:
当你尝试自己把东西从冰箱里拿出来的时候,你可能会带来一些问题:你可能会忘记关冰箱门,你可能会拿到父母不想让你拿到的东西,甚至,你可能会正在寻找我们还没有,或者已经过期的东西。
你应该做的是陈述一个需求,比如,“我午餐需要喝点东西”,然后,当你坐下吃饭时,父母会确保你有东西吃。
5岁的孩子应该依赖父母提供必要的服务。换句话说,协作类应该依赖基础设施提供必要的服务。
这就是关于DI的三种最流行的解释。
DI的目的
DI 本身并不是一个目的,而是达到目的的一种手段。
我们前面说过,DI不过是用来实现松散耦合的一种编程技巧。也就是说,DI的直接目的,就是实现松散耦合。
而松散耦合使代码易扩展,可扩展性使代码易维护,可维护性是使软件尽可能高效地交付的其中一个方面。也就是说,DI的最终目的,跟大多数编程技巧一样,都是尽可能高效地交付软件。
DI的好处
使用DI,可以编写出松散耦合的代码,而松散耦合能带来很多好处,包括:后期绑定、并行开发、可扩展性、可维护性、可测试性。
关于DI的常见误解
关于DI 最最常见的误解是,认为DI跟IoC是同一个概念,进而又产生另一个很常见的误解,认为使用DI时必须有一个DI容器。
我们前面说过,DI是一种编程技巧,是把依赖项注入到对象中的编程技巧。
IoC是一种编程风格,是把对程序流的控制进行反转,把对程序流的控制权交出去的编程风格。从由我自己的代码控制程序流,变成由框架或运行时控制程序流。
其实,使用DI时,并不是必须要有一个DI容器。不使用DI容器的DI,称为纯DI。使用DI容器的DI,其本质就是,在DI编程技巧的基础上,引入了IoC编程风格。