相信接触过Spring的同学,对于依赖注入并不陌生。

刚开始在听说这个名字的时候,一直不明白到底什么叫依赖注入,后来才发现,依赖注入一直都存在我们日常代码中,只是我们没有刻意的把它提出来,然后再取这样一个名字。

最开始我们在定义一个类的时候它往往会依赖于其他的类,比如拼写检查器依赖于字典:

作为工具类,我们一般是声明为静态工具类的:

public class SpellChecker {
private static final EnglishDic dictionary=new Lexicon();

//禁止实例化
private SpellChecker(){} public static boolean isValid(String word){} public static List<String> suggestions(String typo){}
}

或者将SpellChecker定义为单例的:

public class SpellChecker {
private final EnglishDic dictionary = ...; private SpellChecker(...) {}
public static INSTANCE = new SpellChecker(...); public boolean isValid(String word) { ... }
public List<String> suggestions(String typo) { ... }
}

可以看到我们是依赖于EnglishDic类的,假如这个时候项目已经完成并且发版,这个时候老板说有个德国的客户想要使用咱们库,希望咱们同时支持德语。这个时候,我们不得不修改代码将EnglishDic修改为GermanDic,然后再发一版。

后来随着业务扩展越来越大,需要支持各种语言,如果依然用这种方式存在的话,那么我们将维护几十个版本。这个时候,聪明的人就会想到,dictionary不在刚开始就定义好,而是作为可变属性,在用户使用的时候自己传递一个字典对象来,这样我们就只用维护一个版本即可。

此时我们有两个选择

一个是增加一个setter。(当然这是不可行的,因为你无法保证用户什么时候调用setter,而且比较笨拙)

其实我们可以看到上面的需求已经改变,因为后来的需求变为了每个用户希望拥有定制化的字典属性,所以我们抛弃静态工具类的设置,而使用依赖注入

// Dependency injection provides flexibility and testability
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) { ... }
}

这样客户需要使用什么字典都由客户自己决定,而我们的代码也不需要维护多份。

依赖注入通俗的解释就是将类所依赖的对象作为参数让使用者在调用的时候注入

这样能够使代码更加灵活。

依赖注入什么时候用呢?

当一个类依赖于另外一个可变的类的时,可变的类应该使用注入的方式初始化

在实际情况中,一个类可能依赖很多个类的对象。这个时候可以结合使用builder方式构建。

或者:Spring了解一下。

《Effective Java》 读书笔记(五)使用依赖注入取代原本的资源依赖的更多相关文章

  1. 5. Effective Java 第三版——使用依赖注入取代硬连接资源

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  2. Effective Java 第三版——5. 使用依赖注入取代硬连接资源

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  3. Effective java读书笔记

    2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己 计在16年要看12本书,主要涉及java基础.Spring研究.java并发.J ...

  4. Effective Java读书笔记完结啦

    Effective Java是一本经典的书, 很实用的Java进阶读物, 提供了各个方面的best practices. 最近终于做完了Effective Java的读书笔记, 发布出来与大家共享. ...

  5. Effective java 读书笔记(2)

    第四条:通过私有构造器强化不可实例化的能力 有时可能需要编写只包含静态方法和静态域的类,这样的工具类不希望被实例化,因为实例化对它来说没有意义. 然而,在缺少显式构造器的情况下,系统会自动提供一个缺省 ...

  6. Effective Java 读书笔记(一):使用静态工厂方法代替构造器

    这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文&l ...

  7. Effective Java 读书笔记(一):创建和销毁对象

    1 构造器 => 静态工厂方法 (1)优势 静态工厂方法有名字 静态工厂方法不必在每次被调用时都产生一个新的对象 静态工厂方法能返回原返回类型的任意子类型的对象 静态工厂方法根据调用时传入的不同 ...

  8. Effective Java读书笔记--创建和销毁对象

    1.优先考虑用静态工厂方法代替构造器2.遇到多个构造器参数时要考虑使用构建器Builder解决参数过多,不可变类型.私有构造方法,静态类的构造方法提供必要参数,剩下可选.new xxx.build() ...

  9. Effective Java 读书笔记(五):Lambda和Stream

    1 Lamdba优于匿名内部类 (1)DEMO1 匿名内部类:过时 Collections.sort(words, new Comparator<String>() { public in ...

随机推荐

  1. 一个随意list引发的惨案(java到底是值传递还是引用 传递?)

    前两天写了一个递归,因为太年轻,把一个递归方法需要用到的list定义该递归方法外了,结果开始断点测试的时候有点小问题 ,然后上线之后因为数据量太多导致了一个java.util.ConcurrentMo ...

  2. MongoDB 学习笔记之 GridFS

    GridFS: GridFS 是 MongoDB 的一个用来存储/获取大型数据(图像.音频.视频等类型的文件)的规范.它相当于一个存储文件的文件系统,但它的数据存储在 MongoDB 的集合中.Gri ...

  3. 那些初学python犯过的小白错误(学习笔记1)

    一.关于print函数 区别于c和py2,py3的print的正确形式如下:print("hello world") 错误语句:print"hello world&quo ...

  4. display:none和visibility:hidden的区别?

    css控制元素不可见的方法 { display: none; /* 不占据空间,无法点击 */ } /************************************************* ...

  5. 章节十七章、2- 给执行失败的case截图

    一.案例演示 1.首先我们把截图的方法单独进行封装方便以后调用. package utilities; import java.io.File; import java.io.IOException; ...

  6. Orecle基本概述(1)

    Orecle1.什么是orecle及体系结构?* 全局数据库,指物理磁盘数据库,一个真实存在的磁盘目录.*用户: 用户在oracle里面是用来隔离数据的*表空间: 逻辑结构,不可视的,虚拟的,用户的数 ...

  7. Python flask 构建可扩展的restful apl☝☝☝

    Python flask 构建可扩展的restful apl☝☝☝ Flask-RESTful是flask的扩展,增加了对快速构建REST API的支持.Flask-RESTful通过最少的设置鼓励最 ...

  8. 代码审计-phpcms9任意文件读取

    漏洞文件: /phpcms/modules/content/down.php download函数 这个函数开始几行代码的作用和init函数中的几乎一样,都是从parse_str 解析传入的a_k参数 ...

  9. 掌握git基本功

    前言 最近想把代码传到GitHub上,结果我发现的demo的npm全是本地安装,上穿到GitHub要死要死,几百M,然后我就搜了下怎么不上传node_modules弄了半天也没成功,于是准备静下心学一 ...

  10. ‎Cocos2d-x 学习笔记(14.1) Event EventCustom EventListener

    1. Event EventCustom 所有事件类继承了Event. Event中的枚举,定义了事件的类型: enum class Type { TOUCH, //触摸 KEYBOARD, //键盘 ...