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

这篇具有很好参考价值的文章主要介绍了Effective Java笔记(5)优先考虑依赖注入来引用资源。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        有许多类会依赖一个或多个底层的资源 。 例如,拼写检查器需要依赖词典 。 因此,像下面这样把类实现为静态工具类的做法并不少见(详见第 4 条):

// Inappropriate use of static utility - inflexible & untestable!
public class SpellChecker {
    private static final Lexicon dictionary = ...;
    private SpellChecker() {} // Noninstantiable
    public static boolean isValid(String word) { ... }
    public static List<String> suggestions(String typo) { ... }
}

        同样地,将这些类实现为 Singleton 的做法也并不少见(详见第 3 条) :

// Inappropriate use of singleton - inflexible & untestable!
public class SpellChecker {
    private final Lexicon dictionary = ...;
    private SpellChecker(...) {}
    public static INSTANCE = new SpellChecker(...);
    public boolean isValid(String word) { ... }
    public List<String> suggestions(String typo) { ... }
}

        以上两种方法都不理想,因为它们都是假定只有一本词典可用 。 实际上,每一种语言都有自己的词典,特殊同汇还要使用特殊的词典 。 此外,可能还需要用特殊的词典进行测试 。 因此假定用一本词典,就能满足所有需求,这简直是痴心妄想 。

        建议尝试用 SpellChecker 来支持多词典,即在现有的拼写检查器中,设 dictionary域为 nonfinal ,并添加一个方法用它来修改词典,但是这样的设置会显得很笨拙、容易出错,并且无法并行工作 。 静态工具类和 Singleton 类不适合于需要引用底层资源的类 。

        这里需要的是能够支持类的多个实例(在本例中是指 SpellChecker ),每一个实例都使用客户端指定的资源(在本例中是指词典) 。 满足该需求的最简单的模式是, 当创建一个新的实例时 , 就将该资源传到构造器中 。 这是依赖注入( dependency injection )的一种形式:词典(dictionary )是拼写检查器的一个依赖( depend ency ),在创建拼写检查器时就将词典注入( injected )其中 。

// 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) { ... }
}

        依赖注入模式就是这么简单,因此许多程序员使用多年,却不知道它还有名字呢 。 虽然这个拼写检查器的范例中只有一个资源(词典),但是依赖注入却适用于任意数量的资源,以及任意的依赖形式 。 依赖注入的对象资源具有不可变性,因此多个客户端可以共享依赖对象(假设客户端们想要的是同一个底层资惊)。依赖注入也同样适用于构造器、静态工厂和构建器 。

        这个程序模式的另一种有用的变体是,将资源工厂( factory )传给构造器 。 工厂是可以被重复调用来创建类型实例的一个对象 。 这类工厂具体表现为工厂方法( Factory Method) 。 在 Java 8 中增加的接口 SupplierT>,最适合用于表示工厂 。带有 Supplier<T>的方法,通常应该限制输入工厂的类型参数使用有限制的通配符类型( bounded wildcard type ),以便客户端能自多传入一个工厂,来创建指定类型的任意子类型 。 例如,下面是一个生产马赛克的方法,它利用客户端提供的工厂来生产每一片马赛克 :

Mosaic create(Supplier<? extends Tile> tileFactory) { ... }

        虽然依赖注入极大地提升了灵活性和可测试性,但它会导致大型项目凌乱不堪,因为它通常包含上千个依赖 。 不过这种凌乱用一个依赖、注入框架( dep endency injection framework )便可以终结,如 Dagger 、Guice或者 Spring。 

        总而言之,不要用 Singleton 和静态工具类来实现依赖一个或多个底层资源的类,且该资源的行为会影响到该类的行为;也不要直接用这个类来创建这些资源 。 而应该将这些资源或者工厂传给构造器(或者静态工厂,或者构建器),通过它们来创建类 。 这个实践就被称作依赖注入,它极大地提升了类的灵活性 、 可重用性和可测试性 。文章来源地址https://www.toymoban.com/news/detail-554586.html

到了这里,关于Effective Java笔记(5)优先考虑依赖注入来引用资源的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Effective第三版 中英 | 第2章 创建和销毁对象 | 当面临多个参数的构造器时考虑使用构建器

    大家好,这里是 Rocky 编程日记 ,喜欢后端架构及中间件源码,目前正在阅读 effective-java 书籍。同时也把自己学习该书时的笔记,代码分享出来,供大家学习交流,如若笔记中有不对的地方,那一定是当时我的理解还不够,希望你能及时提出。如果对于该笔记存在很多疑惑,

    2024年02月07日
    浏览(43)
  • 6.3Java EE——控制反转与依赖注入

    一、控制反转的概念 传统面向对象程序设计原则         控制反转(Inversion of Control,缩写为IoC)是面向对象编程中的一个设计原则,用来降低程序代码之间的耦合度。在传统面向对象编程中,获取对象的方式是用new主动创建一个对象,也就是说应用程序掌握着对

    2024年02月16日
    浏览(34)
  • Effective Java笔记(6)避免创建不必要的对象

            一般来说,最好能重用单个对象,而不是在每次需要 的时候就创建一个相同功能的新对象 。 重用方式既快速,又流行 。 如果对象是不可变的( immutable ) (详见第 17 条),它就始终可以被重用 。         作为一个极端的反面例子,看看下面的语句 :    

    2024年02月15日
    浏览(36)
  • effective c++ 20 传引用代替传值

    本节,作者开始讨论引用。我们知道c语言已经有了指针,通过指针我们也就可以修改变量本身,而不是修改变量的副本(传值), 那么在c++中又搞出来个引用, 那么其是不是有点重复? 我们知道在函数的传参中,如果传递的是指针, 那么就不可避免的要进行取地址和解引

    2024年02月05日
    浏览(44)
  • Spring学习笔记(二)Spring的控制反转(设计原则)与依赖注入(设计模式)

    是一种设计原则,降低程序代码之间的耦合度 对象由Ioc容器统一管理,当程序需要使用对象时直接从IoC容器中获取。这样对象的控制权就从应用程序转移到了IoC容器 依赖注入是一种消除类之间依赖关系的设计模式。例如,A类要依赖B类,A类不再直接创建B类,而是把这种依赖

    2024年02月19日
    浏览(37)
  • Effective Java笔记(11)覆盖 equals 时总要覆盖 hashCode

             在每个 覆盖了 equals 方法的类中,都 必须 覆盖 hashCode 方法 。 如果不这样做的话,就会违反 hashCode 的通用约定,从而导致该类无法结合所有基于散列的集合一起正常运作,这类集合包括 HashMap 和 HashSet 。 下面是约定的内容,摘自 Object 规范: 1、在应用程序的执

    2024年02月15日
    浏览(55)
  • Effective Java笔记(3)用私有构造器或者枚举类型强化 Singleton 属性

            Singleton 是指仅仅被实例化一次的类 。Singleton 通常被用来代表一个无状态的对象,如函数,或者那些本质上唯一的系统组件 。 使类成为 Singleton会使它的害户端测试变得十分困难 ,因为不可能给 Singleton 替换模拟实现,除非实现一个充当其类型的接口 。      

    2024年02月15日
    浏览(51)
  • Effective Java笔记(9)try-with-resources 优先于 try -finally

            Java 类库中包括许多必须通过调用 close 方法来手工关闭的资源 。 例如 InputStream 、OutputStream 和 java.sql.Connection 。 客户端经常会忽略资源 的关闭 ,造成严重的性能后果也就可想而知了 。 虽然这其中的许多资源都是用终结方法作为安全网,但是效果并不理想。  

    2024年02月15日
    浏览(50)
  • Spring-2-深入理解Spring 注解依赖注入(DI):简化Java应用程序开发

      掌握纯注解开发依赖注入(DI)模式 学习使用纯注解进行第三方Bean注入 问题导入 思考:如何使用注解方式将Bean对象注入到类中 1.1 使用@Autowired注解开启自动装配模式(按类型) 说明:不管是使用配置文件还是配置类,都必须进行对应的Spring注解包扫描才可以使用。@Autowired默

    2024年02月14日
    浏览(57)
  • Effective Java笔记(16)要在公有类而非公有域中使用访问方法

            有时候,可能需要编写一些退化类,它们没有什么作用,只是用来集中实例域 :         由于这种类的数据域是可以被直接访问的,这些类没有提供 封装 ( encapsulation )的功能。 如果不改变 API,就无法改变它的数据表示法, 也无法强加任何约束条件;当域

    2024年02月16日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包