• 《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){}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

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

    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){}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    但是以上两种方法都不太理想,因为上面的方法都是假设只有一本词典可以用,实际上不同国家的语法通常是不一样的,所以建议的方法是可以设置 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){}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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



    3. 依赖注入

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

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

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






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

  • 相关阅读:
    RuoYi-Vue Spring Security 配置介绍
    c++ Makefile clion ide remote构建
    Instagram Shop如何开通?如何销售?最全面攻略
    【Spring】——3、自定义TypeFilter指定@ComponentScan注解的过滤规则
    python基础语法(八)
    文件夹名称提取到excel,批量提取
    计算机毕业论文选题java毕业设计软件源代码SSH权限管理系统[包运行成功]
    python基础05 循环 变量 函数组合案例
    nvm 配置国内镜像
    JAVA学习--DAY1
  • 原文地址:https://blog.csdn.net/laohuangaa/article/details/125600477