Tip1. 考虑用静态工厂方法替代构造器
优势
- 静态工厂方法有名称,能够确切的描述正被返回的对象。
- 当一个类需要多个相同签名的构造器时,用静态工厂方法替代它们。
- 静态工厂方法不必在每次调用它们的时候都创建一个新对象。这可以用于实现实例受控的类,包括单例、FlyWeight模式、不可变类的实例equals问题、枚举类等等。
- 静态工厂方法可以返回原返回类型的任何子类型的对象。这样的接口可以返回对象,又不会使对象的类变为公有。这项技术适用于基于接口的框架(interface-based framework)。例如Java集合框架的类java.util.Collections。
在创建参数化类型实例的时候,可以使代码变得更加简洁。
比如用:
public static <K,V> HashMap<K,V> newInstance(){
return new HashMap<K,V>();
}
来代替下面冗长的声明:
Map<String,List<String>> m = new HashMap<String,List<String>>();
缺点
- 如果因为使用静态工厂方法,导致类不含有public或protected 构造器,从而不能被子类化。(所以用组合,不要用继承)
- 它们与其它的静态方法无法被明确区分,不像构造器那样在api文档中被明确的标识出来。
所以,在类或接口注释中关注静态工厂,使用一些约定俗成的命名。
Tip2. 遇到多个构造器参数时考虑用Builder
使用重叠构造器模式。在类中提供一个只有必要参数的构造器,然后第二个构造器有1个可选参数,第三个构造器有2个可选参数,以此类推。
参数越多越难以编写和阅读
提供一个无参构造器,其它参数通过setter传入。
可读性好,调试困难,不够安全
使用Builder模式
- 易于阅读和编写
- 更安全
Tip3. 用私有构造器或枚举强化单例属性
Effective 中文第二版,page.15:
单元素的枚举类型已经成为实现Singleton的最佳方法。
Tip4.通过私有构造器强化不可实例化的能力
有些类(utility class)不希望被实例化,实例化它们没有任何意义。甚至可以在私有构造器抛出一个错误或异常,调试时保证任何地方都不会调用这个私有构造器。
Tip5.避免创建不必要的对象
- 尽量调用工厂方法来获取需要的对象
- 在可能被调用多次的方法中,尽量避免创建对象,如果需要,就在初始化时创建
- 优先使用基本类型,而不是装箱基本类型,要当心无意识的自动装箱
- 一般来说,普通小对象的构造和回收是非常廉价的,如果通过创建附加的对象,使程序更清晰、简洁、易用,这通常是件好事。
- 通过维护自己的对象池来避免创建对象并不是好的做法,除非池中的对象是重量级的,比如数据库连接池。