- 解释
有许多类会依赖一个或多个底层的资源,这些资源不应该被直接实例化,例如将该类实现为静态工具类:
public class Rule5 {
private static final Lexicon dictionary = new Lexicon();
private Rule5() { } // Noninstantiable
public static boolean isValid(String word) {...}
public static List<string> suggestions(String typo) {...}
}
/<string>
或者实现为单例:
public class Rule5 {
private final Lexicon dictionary = new Lexicon();
private Rule5() { }
public static INSTANCE = new Rule5(...);
public boolean isValid(String word) {...}
public List<string> suggestions(String typo) {...}
}
/<string>
以上两种做法都不够灵活,不可测试,不支持字典类的替换,比如当Lexicon类不满足需要,需要替换为其他类时,该代码不能满足。
应该把依赖的资源类的实例化工作交出去,然后注入进来,例如:
public class Rule5 {
private final Lexicon dictionary;
public Rule5(Lexicon dictionary) {
this.dictionary = Objects.requireNonNull(dictionary);
}
public boolean isValid(String word) {...}
public List<string> suggestions(String typo) {...}
}
/<string>
依赖注入包括:构造器注入、静态工厂注入和构建器注入等。
该模式的一种非常实用的变体:向构造函数传递一个资源的工厂类。Java8可用Supplier
- 优点1:极大地提升了类的灵活性、可重用性和可测试性
依赖的底层类的实例化由框架负责,依赖类的变化不会影响使用者。
- 缺点1:大型项目会比较混乱
大型项目中,可能会有数千个依赖,如果没有依赖注入框架支持将会非常混乱。
- 最佳实践
Spring框架已经成为业界公认的依赖注入标准框架,支持setter注入,构造器注入,工厂方法注入等等,其中,由于构造器注入可能会存在大量的构造器参数,能使程序变得笨拙,特别是当某些属性是可选的时候。因此通常情况下,Spring开发团队提倡使用setter注入。需给每个需要注入的属性设置Setter方法。
专业从事软件研发工作多年,在软件设计、开发、测试、研发管理等领域里经验丰富,感兴趣的朋友可以关注我的头条号,相信一定会有所收获。
如果有软件研发方面的问题,可以咨询我。
谢谢!
閱讀更多 IT極客老兵 的文章