考虑使用静态工厂模式代替构造函数的优势如下:
1、静态工厂方法与构造器的不同在于,静态工厂方法有名字,而构造器没有(构造器与类名称相同),例如:
构造器People()返回的可能是男人也可能返回女人(假设),而People.getMan()则可以根据性别去只返回男人,People.getWoman可以根据性别去只返回女人。
2、不必每次调用它们都创建一个新对象(根据以下代码思考与单例模式的区别)。
将事先构建好的多个对象缓存起来(比如缓存到一个Map),再需要用的时候get(name)出来即可,这种情况可以减少创建对象的开支。我们可以这样考虑,所谓工厂,工厂里面必定可以生产多个产品,每个产品只提供唯一的服务(单例例)。
代码如下:
Service接口
public interface Service {
void method1();
void method2();
}
Provider接口
public interface Provider {
Service newService();
}
SubService1类继承Service接口,使用单例模式
public class SubService1 implements Service{
private static Service INSTANCE = new SubService1();
private SubService1(){}
public static Service getInstance(){
if(null == INSTANCE){
INSTANCE = new SubService1();
}
return INSTANCE;
}
@Override
public void method1() {
System.out.println("SubService1对象的method1方法");
}
@Override
public void method2() {
System.out.println("SubService1得method2的方法");
}
}
SubService1Provider类实现Provider接口,用来提供SubService1 实例
public class SubService1Provider implements Provider{
@Override
public Service newService() {
return SubService1.getInstance();
}
}
SubService2类实现Service接口,使用单例模式
public class SubService2 implements Service{
private static Service INSTANCE = new SubService2();
private SubService2(){
}
public static Service getInstance(){
if(null == INSTANCE){
INSTANCE = new SubService2();
}
return INSTANCE;
}
@Override
public void method1() {
System.out.println("SubService2对象的method1的方法");
}
@Override
public void method2() {
System.out.println("SubService2得method2的方法");
}
}
SubService2Provider类实现Provider接口,用来提供SubService2 实例
public class SubService2Provider implements Provider{
@Override
public Service newService() {
//System.out.println("在proder2中创建SubService2的对象");
return SubService2.getInstance();
}
}
Services类,类似工厂,根据唯一名字可以从工厂里取得很多Provider,而每个Provider只提供唯一的服务
public class Services {
private Services(){} //将构造器私有化
//Map类似一个篮子,把可能用到的东西存进去,以后要去的时候用它的键
//去取它的值,并且每次取出来的时候都是同一个对象
private static final Map<String, Provider>
providers = new ConcurrentHashMap<String, Provider>();
public static final String DEFAULT_PROVIDER_NAME = "<def>";
public static void registerDefaultProvider(String name, Provider p){
providers.put(name, p);
}
public static Service newInstance(String name){
Provider p = providers.get(name);
if(null == p){
throw new IllegalArgumentException(
"No provider registered with name "+name);
}
return p.newService();
}
}
Test类,做测试
public class Test {
public static void main(String[] args) {
saveProvider(); //保存提供器
Service s1 = Services.newInstance("第一个1号提供器");
System.out.println(s1);
s1.method1();
Service s2 = Services.newInstance("第一个1号提供器");
System.out.println(s2);
s2.method1();
}
//先向工厂缓存提供器,以后要用,直接获取
public static void saveProvider(){
SubService1Provider p1_1 = new SubService1Provider();
SubService1Provider p1_2 = new SubService1Provider();
SubService2Provider p2_1 = new SubService2Provider();
SubService2Provider p2_2 = new SubService2Provider();
SubService2Provider p2_3 = new SubService2Provider();
Services.registerDefaultProvider("第一个1号提供器", p1_1);
Services.registerDefaultProvider("第二个1号提供器", p1_2);
Services.registerDefaultProvider("第一个2号提供器", p2_1);
Services.registerDefaultProvider("第二个2号提供器", p2_2);
Services.registerDefaultProvider("第三个2号提供器", p2_3);
}
}
执行结果:
cn.test.refeparam.designMode.staticFactory.SubService1@47ffccd6
SubService1对象的method1方法
cn.test.refeparam.designMode.staticFactory.SubService1@47ffccd6
SubService1对象的method1方法
可以看出,一个提供器只提供一个服务。
修改main方法:
public static void main(String[] args) {
saveProvider(); //保存提供器
Service s1 = Services.newInstance("第一个1号提供器");
System.out.println(s1);
s1.method1();
Service s2 = Services.newInstance("第二个2号提供器");
System.out.println(s2);
s2.method1();
}
执行结果:
cn.test.refeparam.designMode.staticFactory.SubService1@6094cbe2
SubService1对象的method1方法
cn.test.refeparam.designMode.staticFactory.SubService2@2b04a681
SubService2对象的method1的方法
可以看出,不同提供器提供不同的方法。