Effective_Java_Item01_考虑静态工厂方法替代构造器

Creating and Destorying Objects –第二章

这个章节关系着创建和销毁对象:什么时候和怎样创建它们,何时并且如何避免创建它们,怎样保证它们被销毁用一种合适的方式,并且怎么管理任意的清除行为,这些行为必须在它们的销毁之前。

new knowledge

  1. manner n.方式,习惯,规矩
  2. timely adj 即使的,合适的 adv 及时地
  3. cleanup n 清除
  4. precede v 领先 ,在…之前
  5. probably adv 大概,或许
  6. prime 主要的,可能的 v 作准备
  7. get around 避开,到处走走,有办法应付
  8. end up 结束,死亡
  9. close 紧密的,关的
  10. dispense 分配 分发 免除
  11. be said to be 据说
  12. also 也,而且,同样
  13. compact n.合同,契约 v 使简洁,使紧凑 adj 简洁的
  14. lend vt 贷款 提供

Item 1:考虑静态工厂方法替代构造器

对于一个类传统的方式允许一个客户获取一个实例是提供一个公开的构造。有一种别的技术,这种技术应该成为每个开发者工具包的一部分。一个类可以提供一个公开的静态工厂方法,这个方法是简单的一个静态的方法,该方法返回一个类的实例。这是一个简单的列子来自Boolean(包装原始数据的类对于boolean基本数据类型)。这个方法翻译一个boolean原始数据类型的值进入一个Boolean包装类对象的引用。

1
2
3
public static Boolean valueOf( boolean b ){
return b? Boolean.TRUE : Boolean.FALSE;
}

注意这个静态工厂方法是不相同的对于工厂方法模式来自《设计模式》。这个静态工厂方法在这个项中描述并没有直接等价与《设计模式》。

一个类可以提供它的使用者用静态工厂方法替代,或者另外,公开的构造器有优势并且也有劣势。

静态工厂方法的一个优点在于,不像构造方法,他们有属于自己的名字。如果参数对于一个构造函数做不了什么,描述的对象将被返回,一个静态工厂有一个精心准备的名字会更容易使用,并且致使使用者的代码更容易被阅读。例如:构造函数BigInteger(int,int,Random),这将返回一个
BigInteger,这个是可能主要的,这有更好的表达作为一个静态工厂方法的名字 BigInteger。probablyPrime(这个方法被添加进Java4平台)

一个类可以仅有一个单独的给定签名的构造函数,程序员已经知道避开这种通过提供两种构造函数,这种函数的参数集合不同仅在于它们的参数类型的顺序不同的限制。这是一种很坏的想法。这样一个api的使用者将从来不会记得构造函数是这样,并且结束调用这样一个错误通过这个失误。人们阅读代码,用这些构造函数将不会知道这个代码,要是没有参考类的文档。

因为他们有同样的名字,静态工厂方法将不会共享在前一个段落限制讨论,在这种情况下一个类视乎必须多个相同签名的构造函数,用静态工厂方法替代这些构造方法并且小心地紧密的名字来强调它们的不同。

静态工厂方法的第二个优势是,不像构造函数,它们没有必要创建一个对象在每次它们被调用的时候。这个允许不变的类来提前构造使用一个预先构造好的实例,或者为了缓存一个实例作为它们构建的,并且可以分配它们来避免重复的创建不必要的重复的对象。这个Boolean。valueOf(boolean)方法阐述了这个技术:它从来不创建对象。这个技巧很相似于Flyweight pattern(轻量级模式)【Gramma95】。它可以极大的提高性能如果同等的对象被频繁的请求,尤其是它们是那种创建很昂贵的对象。

静态工厂方法能够返回同样的对象来自重复的调用的这个能力,允许类能够维持严格的控制实例在任何时刻都存在。这样实现的类据说是instance-controlled(实例控制)。有几个原因来写实例控制类。实例控制允许一个类保证它是一个单列或者一个不能实例化。而且,它允许一个不可变的值类来保证没有两个相同的实例存在:a.equals(b)仅仅可能是a==b,也就是同一个对象。这个是轻量级模式的基础【Gramma95】。枚举类型提供了这种保证。

静态工厂方法的第三个优点是,不像构造函数,它们可以返回一个任意它们的返回类型的子类型的一个对象。这个给你极大的灵活在选择返回对象的类。

灵活的应用是一个api可以返回对象,而没有让它们的类公开。隐藏实现类用这种流行导致一个非常简洁的API。这个技术提供它自身对于interface-based framework(Item 20)(接口基础框架),在这里接口提供自然的返回类型对于用静态工厂方法。