java提出的依赖注入标准,有别于如下传统的对象获取方式java
开发过程当中是会有不少层层依赖的对象的,例如,Stopwatch依赖于TimeSource,为当前对象寻找一个所依赖对象的实例称作解决依赖,若没有实例被找到,则应用执行失败,咱们称依赖不知足服务器
当没有依赖注入时,也有不少解决依赖的方法,例如直接调用构造器单元测试
class Stopwatch { final TimeSource timeSource; Stopwatch() { timeSource = new AtomicClock(...); } void start() {...} void stop() {...} }
若是须要更多的灵活性,可使用工厂方法测试
class Stopwatch { final TimeSource timeSource; Stopwatch() { timeSource = DefaultTimeSource.getInstance(); } void start() {...} void stop() {...} }
咱们必须权衡这两种方式:this
并且,这几种方法都限制了单元测试,例如,若是咱们使用工厂方法,全部依赖于依赖于工厂类的测试代码都须要模拟出factory,还要记得在用完以后清理掉它pwa
void testStopwatch() { // 先获取原始的实例 TimeSource original = DefaultTimeSource.getInstance(); // 用mock数据替换原始实例 DefaultTimeSource.setInstance(new MockTimeSource()); try { Stopwatch sw = new StopWatch(); ... } finally { // 将原始实例放回去以免一些风险 DefaultTimeSource.setInstance(original); } }
实践经验告诉咱们,模拟factor会致使大量的模式化代码,大量的模拟和清理将会很快失控。code
依赖注入解决了全部的这些问题对象
class Stopwatch { final TimeSource timeSource; @Inject Stopwatch(TimeSource timeSource) { this.timeSource = timeSource; } void start() {...}; void stop() {...}; }
构造器进一步的将依赖层层传递,直到知足所有依赖。例如,咱们须要构造一个StopwatchWidget实例:开发
class StopwatchWidget { @Inject StopwatchWidget(Stopwatch sw) {...} }
构造器作了什么get
这使咱们的代码看起来更加简洁和灵活,并从必定程度上弱化了依赖关系
在测试用例中,咱们也能够直接经过像构造器传递模拟数据进行单元测试,不再须要设置/清理factories了
void testStopwatch() { Stopwatch sw = new Stopwatch(new MockTimeSource()); }