第1条:考虑用静态工厂方法(static factory method)替代构造函数
好处一:
静态工厂方法有自己的名字,可以根据静态工厂方法的名字而不是构造函数的个数或者顺序来创建不同的对象,可以使类更容易被使用同时相应的客户代码更容易阅读。
好处二:
静态工厂方法每次被调用的时候不要求非得创建一个新对象,可以使用一个预先创建好的实例(一些非可变类)或者把已有的实例缓存起来,避免不必要的重复创建对象。
应用场景:频繁创建相同的对象并且创建代价昂贵。例如:Boolean.valueOf(boolean) 注:设计模式之singleton。
好处三:
静态工厂方法可以返回一个原返回类型的子类的对象,并且可以根据参数的不同返回不同的子类。隐藏了返回类的实现细节。
坏处一:采用静态工厂方法创建对象,如果该类不含有public或者受保护protected的构造函数则该类不能被继承。 注:从反面来讲更鼓励组合而不是继承。
坏处二:静态工厂方法不能与其他的静态方法区别开。但可以遵循一些命名规范:valueOf()多用于类型转换。getInstance多用于单例模式
注意:如果静态工厂方法没有明显的优势的话则选择构造函数的方式创建对象,毕竟它是语言提供的规范。
第2条:使用private构造函数强化singleton属性
第一种方法:private构造函数,public的final的共有静态成员,私有构造函数在初始化final成员变量的时候被调用一次。
public class Elvis {
// 共有静态变量--只在创建的时候调用一次构造函数
public static final Elvis INSTANCE = new Elvis();
// 私有构造函数--确保全局唯一性
private Elvis(){
}
}
第二种方法:private构造函数,private的final的共有静态成员,public的静态工厂方法
public class Elvis {
// 私有静态变量--只在创建的时候调用一次构造函数
private static final Elvis INSTANCE = new Elvis();
// 私有构造函数--确保全局唯一性
private Elvis(){
}
// 共有静态工厂方法
public static Elvis getInstance() {
return INSTANCE;
}
}
注意:为了使一个singleton类能够序列化,首先需要实现Serializable结构,同时要加入
readResolve方法防止在每次被反序列话的时候都产生一个新的对象
private Object readResolve() throws ObjectStreamException {
// instead of the object we're on,
// return the class variable INSTANCE
return INSTANCE;
}
其他联想:
饿汉式:
public class Singleton{
private static Singleton singleton = new Singleton ();
private Singleton (){}
public Singleton getInstance(){return singletion;}
}
懒汉式:
public class Singleton{
private static Singleton singleton = null;
public static synchronized synchronized getInstance(){ // 一定要同步
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}