用静态工厂方法代替构造器
优点
1.静态工厂方法与构造器不同的第一大优势,他们有名称
2.静态工厂不必在每次调用他们的时候都创建一个新对象
3.静态工厂可以返回原返回类型的任何子类型的对象???
4.静态工厂锁返回的对象的类可以随着每次调用二发生变化,这取决于静态工厂方法的参数值
5.静态工厂方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在
缺点
1.静态工厂如果不含有共有的或者受保护的构造器,就不能被子类化
2.静态工厂的第二个缺点在于,程序员很难发现它们【规范命名】
遇到多个构造器参数时要优先考虑使用构造器
如果类的构造器或者静态工厂中具有多个参数,设计这种类时,builder模式是一种不错的选择,特别是当大多数参数都是可选或者类型相同的时候,与使用重叠构造器模式相比,使用buider模式的客户端代码将更易于阅读和编写,构造器也比javaBeans更安全
用私有构造器或者枚举类型强化Singleton属性
公有域方法:
1.很清楚的表明了这个类是一个Singleton:共有的静态域是final的,所以该域总是包含相同的对象引用
2.很简单
静态工厂方法:
1.提供了灵活性:在不改变API的前提下,可以改变该类是否为Singleton的想法
2. 如果应用程序需要,可以编写一个泛型Singleton工厂
3.可以通过方法引用作为提供者,比如Elvis::instance就是一个Supplier<Elvis>
4.除非满足静态工厂的任何一种优势,否则优先考虑公有域方法
声明一个包含单个元素的枚举类型。单元素类型经常成为实现Singleton的最佳方法。注意,如果Singleton必须扩展一个超类,而不是扩展Enum的时候,则不宜使用这种方法
// Enum Singleton - the prefered approach
public enum Elvis{
INSTANCE;
public void leaveTheBuilding(){...}
}
注意:客户端的任何行为都不会改变Singleton的类只存在一个实例,但是享有特权的客户端可以借助AccesssibleObject.setAccessible方法,通过反射调用私有构造器,如果需要抵御这种攻击,可以修改构造器,让它被要求创建第二个实例的时候抛出异常。
通过私有构造器强化不可实例化的能力
让这个类包含一个私有的构造器,它就不能被实例化。但是这似的一个类不能被子类化(所有的构造器都必须显式地调用超累构造器,在这种情形下,子类就没有可访问的超类构造器用了)。
优先考虑依赖注入来引用资源
不要用Singleton和静态工具来实现依赖一个或多个底层资源的类,且该资源的行为会影响到该类的行为;也不要直接用这个类来创建这些资源。而应该将这些资源或者工厂传给构造器(或者静态工厂,或者构造器),通过它们来创建类。这个实践就被称作依赖注入,它极大的提升了类的灵活性、可重用性和可测试性。
避免创建不必要的对象
1.有些对象创建的成本比其他对象要高得多。如果重复地需要这类“昂贵地对象”,建议将它缓存下来重用
2.另一种创建多余对象地方法,称作自动装箱。自动装箱似的基本类型和装箱基本类型之间的差别变得模糊起来,但是并没有完全消除。要优先使用基本类型而不是装箱类型,要当心无意识的自动装箱
3.注意:在提倡使用保护性拷贝的时候,因宠用对象而付出的代价要远远大于因创建重复对象而付出的代价。必要时如果没能实施保护性拷贝,将会导致潜在的Bug和安全漏洞;而不必要的创建对象则只会影响程序的风格和性能