Files
effective-Java/ch02创建和销毁对象/05.使用依赖注入取代硬连接资源.md
2019-09-16 20:17:17 +08:00

38 lines
2.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 使用依赖注入取代硬连接资源
### 示例
- [Item05Example01.java](CreatingAndDestroyingObjects/src/main/java/com/jueee/item05/Item05Example01.java)
### 说明
许多类依赖于一个或多个底层资源。
例如,拼写检查器依赖于字典。
满足这一需求的简单模式是在创建新实例时将资源传递到构造方法中。
这是依赖项注入dependency injection的一种形式字典是拼写检查器的一个依赖项当它创建时被注入到拼写检查器中。
```java
// 依赖注入提供了灵活性和可测试性
public class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = Objects.requireNonNull(dictionary);
}
public boolean isValid(String word) { ... }
public List<String> suggestions(String typo) { ... }
}
```
虽然我们的拼写检查器的例子只有一个资源(字典),但是依赖项注入可以使用任意数量的资源和任意依赖图。 它保持了不变性(条目 17因此多个客户端可以共享依赖对象假设客户需要相同的底层资源。 依赖注入同样适用于构造方法,静态工厂(条目 1和 builder模式条目 2
该模式的一个有用的变体是将资源工厂传递给构造方法。 工厂是可以重复调用以创建类型实例的对象。 这种工厂体现了工厂方法模式Factory Method pattern )。 Java 8中引入的`Supplier <T>`接口非常适合代表工厂。 在输入上采用`Supplier<T>`的方法通常应该使用有界的通配符类型( bounded wildcard type)(条目 31约束工厂的类型参数以允许客户端传入工厂创建指定类型的任何子类型。 例如下面是一个使用客户端提供的工厂生成tile的方法
`Mosaic create(Supplier<? extends Tile> tileFactory) { ... }`
尽管依赖注入极大地提高了灵活性和可测试性,但它可能使大型项目变得混乱,这些项目通常包含数千个依赖项。使用依赖注入框架(如Dagger、Guice或Spring)可以消除这些混乱。
总之,不要使用单例或静态的实用类来实现一个类,该类依赖于一个或多个底层资源,这些资源的行为会影响类的行为,并且不让类直接创建这些资源。相反,将资源或工厂传递给构造方法(或静态工厂或builder模式)。这种称为依赖注入的实践将极大地增强类的灵活性、可重用性和可测试性。