Effective 建造者模式、私有化、依赖注入
Effective 2 遇到多个构造器参数时要考虑使用构建器(建造者模式)
Effective 3 用私有构造器或者枚举类型强化SingleTon属性
-
方法一
public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis() {} }
私有构造器仅被调用一次,用来实例化公有的静态final域Elvis.INSTANCEl。由于缺少公有的或受保护的构造器,所以保证了Elvis的全局唯一性:一旦Elvis类被实例化,将会只存在一个Elvis实例。客户端的任何行为都不会影响这一点
但是,反射可以改变借助 AccessibleObject.setAccessible方法通过反射机制调用私有构造器。如果需要抵御这种攻击,可以修改构造器,让他在要求创建第二个实例的时候抛除异常
-
方法二
public class Elvis { private static final Elvis INSTANCE = new Elvis(); private Elvis() {} public static Elvis getInstance() {return INSTANCE;} }
-
方法三
声明一个包含单个元素的枚举类型
public enum Elvis {
INSTANCE
}
无偿的提供了序列化机制,绝对防止多次实例化,即使是面对复杂的序列化或反射攻击时。
Effective 4 优先考虑依赖注入来引入资源
当创建一个新的实例时,就讲该资源传到构造器中。这就是依赖注入 的一种形式:词典 是拼写检查器的一个依赖,在创建拼写检查器时就将该词典注入其中
public class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = dictionary;
}
// other method
}
虽然依赖注入极大提升了灵活性和可观测性,但他会导致大项目凌乱不堪,因为它通常包含上千个依赖。不过这种凌乱用一个依赖注入框架便可以终结,如Dagger、Guice或者Spring。请注意:设计成手动依赖注入的API,一般都使用于这些框架