《Effective Java》学习笔记 - (5) 优先考虑依赖注入来引用资源


前言

依赖注入在这里的含义就是把一个类当作参数传入到另一个类中。在这一节提到,如果是想要在一个类中使用另一个类的资源,那么最好就是使用依赖注入。




优先考虑依赖注入来引用资源

1. 引出

首先来看一个例子,比如拼写检查其需要依赖词典,所以有时候我们的写法就是将词典作为一个静态对象,然后在工具类中调用词典进行检查:

public class SpellChecker {

    //词典
    private static final Lexicon dictionary = ...;

    private SpellChecker(){}

    //检测拼写
    public static boolean isValid(String word){}
    //建议
    public static List<String> suggestions(String typo){}

}

又或者是这样写(把这个类设置成单例):

public class SpellChecker {

    //词典
    private static final Lexicon dictionary = ...;

    private SpellChecker(...){}
    
    public static SpellChecker INSTANCE = new SpellChecker(...);

    //检测拼写
    public static boolean isValid(String word){}
    //建议
    public static List<String> suggestions(String typo){}

}

但是以上两种方法都不太理想,因为上面的方法都是假设只有一本词典可以用,实际上不同国家的语法通常是不一样的,所以建议的方法是可以设置 dictionary 不是 final 的,然后添加一个方法,这个方法可以修改词典,但是这样写起来会容易出错,可能你检测一个单词就要修改一次词典,如果是多线程情况下就更加麻烦了。所以静态工具类和 Singleton 类不适合于需要引用底层资源的类



2. 解决

当然了,有问题就会有解决的方法,这里我们解决的方法就是不同的实例对应不同的词典,比如中文和英文,那么就有两个实例,然后词典通过构造器传入这个实例中去,这就是依赖注入的一种形式:词典是拼写器的一个依赖,在创建拼写检查器的时候就将词典注入其中

public class SpellChecker {

    //词典
    private final Lexicon dictionary;

    public SpellChecker(Lexicon dictionary){
        this.dictionary = dictionary;
    }
    
    //检测拼写
    public static boolean isValid(String word){}
    //建议
    public static List<String> suggestions(String typo){}

}

这就是依赖注入模式,虽然这个拼写检查器的范例中只有一个资源,但是依赖注入适合于任何数量的资源以及任意的依赖形式。所以可以看到的是,我们如果想要完成词典检查器的完整功能,只需要使用一个 List 或者一个 Map 把词典存起来,然后进行调用即可。



3. 依赖注入

上面的例子中,依赖注入的对象资源具有不可变性,里面没有提供可以修改词典的方法。所以多个客户端可以共享依赖对象,依赖注入也同样适合用于构造器、静态工厂和构建器。

这种模式还可以用于工厂方法中,将资源工厂传给构造器,使用工厂来进行创建实例。虽然依赖注入极大地提高了灵活性和可测试性,但是它会导致大型项目非常凌乱,因为一个大型项目通常包含上千个依赖,所以这时候就需要用到依赖注入框架了,像是 Dagger、Guice 或者 Spring。

总之,当一个类需要使用另一个类的资源的时候,不要使用 Singleton 和静态工具类来实现依赖一个或者多个底层资源的类,且资源的行为会影响到类的行为,也不要在这个类中直接创建这些资源,而是应该通过构造器进行依赖注入。






如有错误,欢迎指出!!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值