Effective Java -- 创建和销毁对象 -- 优先考虑依赖注入来引用资源

第二章 创建和销毁对象

第四条 通过私有构造器强化不可实例化的能力

静态工具类不需要被实例化,因此将这个类的构造方法声明为私有的。
(这一条比较简单,跳过)

第五条 优先考虑依赖注入来引用资源

有许多类会依赖一个或多个底层的资源。

一 将资源依赖注入

以一个拼写检查器类举例,拼写检查器需要依赖词典:

下面是两个不合适的做法(静态工具类和Singleton):

/*拼写检查器类 将词典作为静态工具类*/
public class SpellChecker {
	//需要依赖的词典 静态工具类
    private static final Lexicon dictionary = ...;

    private SpellChecker() {
    }
}
/*拼写检查器类 Singleton*/
public class SpellChecker {
	//需要依赖的词典
    private final Lexicon dictionary = ...;
    public static INSTANCE = new SpellChecker(...);

    private SpellChecker(...) {
    }
    
}

这样词典就会被写死在拼写检查器类中。

下面是推荐的做法(依赖注入):

/*拼写检查器类 依赖注入*/
public class SpellChecker {
	//需要依赖的词典
    private final Lexicon dictionary;

	//在构造方法中注入
    public SpellChecker(Lexicon dictionary) {
        this.dictionary = Objects.requireNonNull(dictionary);
    }
}

当创建一个新的实例时,就将该资源传到构造方法中。

这就是依赖注入(DI)的一种形式:词典是拼写检查器的一个依赖(dependency),在创建拼写检查器时就将词典注入(injected)其中。

依赖注入的对象资源具有不可变性,多个客户端可以共享依赖对象。

二 将资源工厂依赖注入

在Java8中增加的接口Supplier<T>,最适合用于表示工厂(下次深入了解一下)。
带有Supplier<T>的方法,应该限制输出工厂的类型参数使用有限制的通配符类型(详见第31条),以便客户端能够传入一个工厂,来创建指定类型的任意子类型。
例如下面是一个生产马赛克的方法:

	//生产马赛克方法
	Mosaic create(Supplier<? extends Tile> tileFactory){
		...
	}

三 依赖注入框架

虽然依赖注入极大地提升了灵活性和可测试性,但会导致大型项目凌乱不堪(通常包含上千个依赖)。
这时就可以利用依赖注入框架来解决,如Spring、Dagger或Guice。

四 总结

不要用静态工具类或Singleton来实现依赖。
应该使用依赖注入,将这些资源或工厂传给构造方法,提高类的灵活性、可重用性和可测试性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值