相信接触过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. 记一次linux Docker网络故障排除经历

    背景: 之前做了一个项目,需要在容器内访问宿主机提供的Redis 服务(这是一个比较常见的应用场景哈), 常规方案: ①   主机网络(docker run --network=host): 完全应用 ...

  2. 洛谷:P3950 部落冲突

    原题地址:https://www.luogu.org/problemnew/show/P3950 题目简述 给定一棵树,每次给定一个操作,有如下两种: 将某条边染黑 2.询问给定的u,v两点间是否有边 ...

  3. js匿名函数自执行的好处

    我们知道,在创建一个函数时如果要用到变量来存取信息的话,要尽量使用局部变量. 因为一方面局部变量会随着函数的执行结束被销毁:另一方面在不执行函数的时候也不会创建这个局部变量,对节省空间资源有很大的好处 ...

  4. Mysql数据类型TINYINT(1)与BOOLEAN踩坑记

    熟悉Mysql的同学应该都知道,Mysql查询的boolean结果将输出为0或者1. 比如: ; 其输出结果为1. 查阅mysql官方文档仅找到如下描述: 11.10 Using Data Types ...

  5. 一次Commons-HttpClient的BindException排查

    线上有个老应用,在流量增长的时候,HttpClient抛出了BindException.部分的StackTrace信息如下: java.net.BindException: Address alrea ...

  6. Java字段初始化规律

    首先先附上一段代码:public class InitializeBlockDemo { public static void main(String[] args) { InitializeBloc ...

  7. System NT Kernel & System占用CPU 12%左右 终极解决方案,原来是更新惹的祸

    任务管理器发现 system进程持续占用12%左右的cpu,网上搜索到的很多方法均无效 误打误撞发现了这个方法,亲测可用 卸载系统补丁(KB41000347),提升10%的cpu性能 卸载补丁前:  ...

  8. django-drf框架自带的路由以及最简化的视图

    0910自我总结 django-drf框架自带的路由以及最简化的视图 路由 一.导入模块 from rest_framework.routers import SimpleRouter 二.初始化路由 ...

  9. JavaScript回调函数和递归函数

    一.回调函数--通过函数的指针来调用函数 把一个函数的指针作为另一个函数的参数,当调用这个参数的时候,这个函数就叫做回调函数 在链式运动上会用到回调函数,之后运动会见到 A.通过指针来调用函数 B.通 ...

  10. Python开发【第二篇】:初始Python

    Python的前世今生 Python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,中国人称他为龟叔,他在圣诞节期间在阿姆斯特丹为了打发时间,决定开发一个新的脚本 ...