依赖注入 Dependency Injection(DI)
第一次接触这个名词时,真的很难从字面意思理解这东西,查了许多资料却发现越看越混乱,也常常看懂原理却跟实作连不起来,所以我将它拆分开来解释并翻译成白话文。
依赖指的是物件导向中的继承、实现、拥有等关係。
注入的意思是从外部传入。
当 A class 有用到 B class 就可以说是 A 对 B 有依赖。
一般使用其他类别时都会实例化 B b = new B()
来使用, 如例1
例1
public class A{ B b = new B(); ...}
而这样设计有个缺点,就是
当B改动时,A就要跟着改,而这有什么问题呢?
当有其他C、D也用到B时,要改动的地方就很多了, 如图一
图一
此种情况就是高度的耦合(依赖),会造成日后程式撰写的诸多不便,因为牵一髮而动全身啊!!
解决方法
改成将B在外部实例化后再传入A
也就是将B当成参数传入A,如例2
例2
public class A{ B b; //建构元注入 public A(B _b) { this.b = _b; } //设值注入 public void a(B _b) { this.b = _b; ... }}
如此改善后,当B改动时,只须跟着改Main中对A、C、D的传入值,如图二
图二
异动的程式只有B跟Main,解掉A、C、D对B的依赖就是依赖注入的目的
如果将B设计成 interface 或是 abstract,则可以让所有继承 B 的类别都能注入,达成更灵活的设计。
而依赖注入的其他方法与衍生问题在这就先不讨论
总结
依赖注入是一种方法,而我们使用依赖注入是为了符合程式设计的原则
,符合程式设计的原则是为了日后维护的便利。