为什么要用静态工厂方法代替构造方法???
- 静态方法有名称。构造器名和类名一致,静态方法名可以自己定义,例如,BigInteger.probalePrime,可读性强.
- 静态方法, 不必每次调用他的时候都新建一个对象。这也是为啥推荐使用Boolean.valueOf(),不推荐new
- 静态方法有返回值,可以返回原返回类型任何子类对象,有更大的灵活性。
- 使代码变得更加简洁
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Services {
private Services(){
}
// Map Service Name to Services
public static final Map<String,Provider> providers = new ConcurrentHashMap<String, Provider>();
public static final String DEFAULT_PROVIDER_NAME = "<def>";
// Provider Register API
public static void registerDefaultProvider(Provider p){
registerProvider(DEFAULT_PROVIDER_NAME,p);
}
public static void registerProvider(String defaultProviderName, Provider p) {
providers.put(defaultProviderName, p);
}
public static Service newInstance(){
return newInstance(DEFAULT_PROVIDER_NAME);
}
public static Service newInstance(String name){
Provider p = providers.get(name);
if(p == null){
throw new IllegalArgumentException("No provider registered with name: " + name);
}
return p.newService();
}
}
静态工厂方法代替构造器去创建对象, 在可读性,不重复new对象,和灵活性,代码更简洁4方面有优势。
测试类:
public class Test {
/**
* 静态工厂方法主要缺点,类如果不含公有的或者受保护的构造器,就不能子类话。
* 静态工厂的第二个缺点在于,他们与其他静态方法实际上没有其他区别。
*
* @param args
*/
public static void main(String[] args) {
// Providers would execute these lines
Services.registerDefaultProvider(DEFAULT_PROVIDER);
Services.registerProvider("comp", COMP_PROVIDER);
Services.registerProvider("armed", ARMED_PROVIDER);
// Clients would execute these lines
Service s1 = Services.newInstance();
Service s2 = Services.newInstance("comp");
Service s3 = Services.newInstance("armed");
System.out.printf("%s, %s, %s%n", s1, s2, s3);
}
private static Provider DEFAULT_PROVIDER = new Provider() {
public Service newService() {
return new Service() {
@Override
public String toString() {
return "Default service";
}
};
}
};
private static Provider COMP_PROVIDER = new Provider() {
public Service newService() {
return new Service() {
@Override
public String toString() {
return "Complementary service";
}
};
}
};
private static Provider ARMED_PROVIDER = new Provider() {
public Service newService() {
return new Service() {
@Override
public String toString() {
return "Armed service";
}
};
}
};
}