1、静态工厂方法
适用:定义公有构造方法之前,考虑使用静态工厂方法替代
简单的一个例子,使用Boolean.valueOf(boolean b)生成包装类,而不是new Boolean(boolean);
优势:
1、有名称,BigInteger
2、不必每次调用都会产生一个新的实例,这样就可以控制某个时刻,只需要某些实例存在。提升性能。并且可以使得不会存在两个不可变类的实例,客户端即可使用 ==代替equals
3、可以返回原返回类型的任何子类的对象。
这里有一个很好的例子:
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum<?>[] universe = getUniverse(elementType);
throw new ClassCastException(elementType + " not an enum");
if (universe == null)
if (universe.length <= 64)
return new JumboEnumSet<>(elementType, universe);
return new RegularEnumSet<>(elementType, universe);
else
}
使用EnumSet.noneOf时,会根据元素的个数返回不同的子类实例。这样客户端就不必关心到底实现了哪些子类,这个问题已经在api中解决了。
4、调用参数较多的构造方法实例化对象时,需要提供一长串参数,像Map<String,List<String>> m = new HashMap<
String,List<String>>();虽然红体字可以省略, 但是也远不如HashMap.newInstance();这样来的简便易懂
缺点:
1、如果缺少公有或保护的构造器,就不能被子类化。
不过这样可以强制让使用者使用复合而不是继承
2、不像构造方法会在javadoc中标识
2、问题考虑?
如果实体类是一个植物plant,它有种类,科目,生长周期等等等等十几个属性,在构建这个实例的时候怎么做?客户端只想添加几个参数进去而不是全部, 怎么办?
通常:对每个属性都创建构造方法,以少至多,无疑很费劲,
使用javabean,setget注入,看似简单,那安全问题怎么解决?再使用同步?freeze?oh no
解决:
Build模式啊,
package com.linoer.effective;
/**
* @author linoer
*
*/
public class Plants {
//属性
//@Unique&&Required
private static int id;
//@Required
private static String name;
private static String code;
private static int cycle;
private static String type;
private Plants(Builder builder){
id = builder.id;
name = builder.name;
code = builder.code;
cycle = builder.cycle;
type = builder.type;
}
public static void main(String[] args) {
Plants p =new Plants.Builder(1, "小麦").code("001").cycle(100).build();
}
public static class Builder{
//required属性
private static int id;
private static String name;
//optional属性
private static String code;
private static int cycle;
private static String type;
public Builder(int id,String name){
this.id = id;
this.name = name;
}
public Builder code(String value){
code = value;
return this;
}
public Builder cycle(int value){
cycle = value;
return this;
}
public Builder type(String value){
type = value;
return this;
}
public Plants build(){
return new Plants(this);
}
}
}
//如果对其优化就可以使Builder继承自Builder<T>,可以参考java源码中的设计。