Effective Java —— 优先考虑依赖注入来引用资源
本文参考
本篇文章参考自《Effective Java》第三版第五条"Prefer dependency injection to hardwiring resources"
Static utility classes and singletons are inappropriate for classes whose behavior is parameterized by an underlying resource
静态工具类模式和单例模式都不适合应用到需要将底层资源作为自身字段进行参数化的类,这个引用的资源可以是一个接口,他对应有很多的实现,不同的实现应对不同的场景
静态工具类模式往往不需要进行实例化,而且有一个无参的private构造方法来强化noninstantiability的特性,他需要引用的资源在类加载时就已经被构建,尽管我们可以再设计一个静态方法来修改引用的资源,但并不是灵活和方便测试的方式
虽然单例模式存在一个实例,但是这个实例仅允许被初始化一次,所以引用的资源也只能被参数化一次,难以按照不同场景下的需求进行改变
do not use a singleton or static utility class to implement a class that depends on one or more underlying resources whose behavior affects that of the class, and do not have the class create these resources directly.
pass the resource into the constructor when creating a new instance
要解决上述问题,便要求能够用不同的资源构建不同的实例,我们可以通过构造方法来实现不同资源的参数化,这就是依赖注入的其中一种解决方案(同样可以应用到前述的静态工厂方法和构建者模式),这与Spring中的"构造注入"类似,它也能够保证不同的客户端共享同一份引用的资源,即"preserves immutability"
pass the resources, or factories to create them( refer to the fields using underlying resources ), into the constructor (or static factory or builder). This practice, known as dependency injection, will greatly enhance the flexibility, reusability, and testability of a class.
a variant of the pattern is to pass a resource factory to the constructor
原文提供了一种使用Supplier<T>接口的Factory Method Pattern(工厂方法模式)
有关Supplier的使用,参考这篇文章:https://mkyong.com/java8/java-8-supplier-examples/
以马赛克为例,工厂方法模式的示例代码如下,顺便复习一下builder构建者模式
public class Tile {
private String name;
private int price;
private String origin;
public static class Builder {
private String name;
private int price;
private String origin;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder price(int price) {
this.price = price;
return this;
}
public Builder origin(String origin) {
this.origin = origin;
return this;
}
public Tile build() {
return new Tile(this);
}
}
private Tile(Builder builder) {
name = builder.name;
price = builder.price;
origin = builder.origin;
}
public String getName() { return name; }
public int getPrice() { return price; }
public String getOrigin() { return origin; }
}
public class Mosaic {
private Tile tile;
private String style;
private Mosaic(String style) {
this.style = style;
}
public static Mosaic create(Supplier<? extends Tile> tileFactory) {
Tile tile = tileFactory.get();
if (tile.getOrigin().equals("American")) {
return new Mosaic("USA-STYLE");
} else {
return new Mosaic("GENERAL_STYLE");
}
}
public Tile getTile() { return tile; }
public String getStyle() { return style; }
}
public class SupplierExample {
public static void main(String[] args) {
Mosaic product = Mosaic.create(() -> new Tile.Builder().origin("American").build());
System.out.println(product.getStyle());
}
}
Effective Java —— 优先考虑依赖注入来引用资源的更多相关文章
- 在ABAP里模拟实现Java Spring的依赖注入
Dependency Injection- 依赖注入,在Java Spring框架中有着广泛地应用.通过依赖注入,我们不必在应用代码里繁琐地初始化依赖的资源,非常方便. 那么ABAP能否从语言层面上也 ...
- Java Spring各种依赖注入注解的区别
Spring对于Bean的依赖注入,支持多种注解方式: @Resource javax.annotation JSR250 (Common Annotations for Java) @Inject ...
- JavaEE(10) - Session EJB的依赖注入、引用及任务调度
1. EJB依赖注入 #1. EJB开发(Net Beans创建EJB Module, 项目名称:CallHello) Hello.java package org.crazyit.service; ...
- JAVA框架 Spring 依赖注入
一:介绍 情景:我们在给程序分层的时候:web层.业务层.持久层,各个层之间会有依赖.比如说:业务层和持久层,业务层的代码在调用持久层的时候,传统方式:new 持久层类. 进而进行调用,这种方式会导致 ...
- 详解Java Spring各种依赖注入注解的区别
注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.Service.Controller.Repository.Comp ...
- 【Java】 Spring依赖注入小试牛刀:编写第一个Spring ApplicationContext Demo
0 Spring的依赖注入大致是这样工作的: 将对象如何构造(ID是什么?是什么类型?给属性设置什么值?给构造函数传入什么值?)写入外部XML文件里.在调用者需要调用某个类时,不自行构造该类的对象, ...
- Effective Java 第三版——43.方法引用优于lambda表达式
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Java代码实现依赖注入
http://zhangjunhd.blog.51cto.com/113473/126545 这里将模仿Spring实现一种基于xml配置文件的依赖注入机制.文件中将实现3中注入,一是单值注入,包括i ...
- Java反射及依赖注入简单模拟
一.编写Dao类 ? 1 2 3 4 5 6 7 8 9 10 11 package cn.com.songjy.annotation; import java.util.Date; publ ...
随机推荐
- 反编译C#代码来看看闭包到底是什么
原文地址:https://zhuanlan.zhihu.com/p/3161634 C#的闭包,是一个语法糖. 它实质上是将匿名函数转换成一个类,函数作为其中的类方法,并调整外部调用代码来实现的.既然 ...
- Zookeeper集群搭建及原理
1 概述 1.1 简介 ZooKeeper 是 Apache 的一个顶级项目,为分布式应用提供高效.高可用的分布式协调服务,提供了诸如数据发布/订阅.负载均衡.命名服务.分布式协调/通知和分布式锁等分 ...
- C语言while循环语句
循环语句三要素 1.在循环外给循环变量赋初值2.进入循环判断循环变量3.在循环体内修改循环变量,使循环趋近结束 2021-11-02
- pyinstaller:各种错误及解决方法
1.DLL load failed 说明没有找到某个DLL 解决方法: 在 D:\Anaconda\Anaconda3\Library\bin 下找到缺失的DLL,复制到dist下 2.No modu ...
- if 、whitch、for、while
if 用于过程的判断 whitch用于值得判断 if { } else if { } else if //当此前的过程满足条件时,程序便不再判断其他过程,但是if{}if{}这样的写法程序会将每个过 ...
- 二级py--day5 软件工程基础
二级py--day5软件工程基础 软件工程基础 1.软件工程三要素:方法.工具和过程 2.软件生命周期可以分为:项目可行性研究与规划.软件需求分析.软件设计.软件实现.软件测试.软件运行与维护等阶段 ...
- 微信小程序实现简单的2048
这两天心血来潮,用微信小程序写了一个简单的2048,欢迎各位老铁围观,提出宝贵意见.这里我从0到1赘述一下个人实现流程: 首先去微信公平台(https://mp.weixin.qq.com/)注册一个 ...
- MATLAB绘制三角网及三维网线
今天博主给大家介绍一些比较常见的可视化操作,绘制三角网及三维网线. 三角网是由一系列连续三角形构成的网状的平面控制图形,是三角测量中布设连续三角形的两种主要扩展形式,同时向各方向扩展而构成网状,优点为 ...
- SQL学习日记
目录 SQL学习日记 1. 常见的数据库对象 2. DDL 定义语句 3. DML 操作语句 4. DQL 查询语句 5. DCL 控制语句 SQL学习日记 1. 常见的数据库对象 对象名 关键字 描 ...
- 解决福大aTrust深信服无法访问部分页面的问题
如果你原先使用过天融信,hosts里会留下 #################################################### Add by VONE SSL VPN Clien ...