静态工厂方法

《Effective Java》的第一章节就介绍了,利用静态工厂的方法来替代构造器。静态工厂方法是返回类实例的一种静态方法。下面是一个经典例子:

public static Boolean valueOf (boolean b) {
      return b ? Boolean.TRUE : Boolean.FALSE;
}

上面的这个静态方法是将boolean 类型的值转换成了一个Boolean 类型的引用。
用静态工厂方法替代公有的构造器有几点优势:
1.静态工厂方法可以设置每个实例自己的名称。这就意味着代码更加易读,所代表的更具体更有意义。
2.静态工厂方法在调用的时候可以不创建新的对象 可以用事先创建好的实例,当然也是可以返回新的实例。更加的灵活。用缓存好的实例会大大降低创建实例的开销成本。就如上面valueOf 方法,返回的一直都是相同的对象而没有返回新的实例。
3.静态工厂方法可以返回原类型的任何子类型的对象 为了更好的理解《Effective Java》 举了一个例子:`

//Service 接口
public interface Service {
	void print();
}

定义一个用于生成Service 实例的一个接口

// Provider 接口
public interface Provider {
    /**
     * @return  返回Service 实例
     */
    Service newService();
}

非实例化的类 Service 进行注册和访问

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class Services implements Service {

    // 禁止外部实例化
    private Services() {
    }

    /*
     * Map service names to services
     * */
    private static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>();
    private static final String DEFAULT_PROVIDER_NAME = "DefaultName";

    //Provider 注册的方法
    public static void registerDefaultProvider(Provider provider) {
        registerProvider(DEFAULT_PROVIDER_NAME, provider);
    }

    public static void registerProvider(String name, Provider provider) {
        providers.put(name, provider);
    }

    // 访问Service 的方法
    public static com.staticFactory.Service newInstance() {
        return newInstance(DEFAULT_PROVIDER_NAME);
    }

    public static com.staticFactory.Service newInstance(String name) {
        Provider provider = providers.get(name);
        if (null == provider) {
            throw new IllegalArgumentException("No registered with name : " + name);
        }
        return provider.newService();
    }
    
    public void print() {
        System.out.println("ok");
    }
}

在书中只是定义了Provider 接口并没有写出如何获得实例对象的过程。所以自己就是实现了一个方法用于返回新的实例的实现类

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ProviderImp implements Provider {
    
    public Service newService() {
        try {
         /*利用反射获取类构造器并破封(可以访问私有的构造)来创建新实例*/
            Class<?> clazz = Class.forName("com.staticFactory.Services");
            /*获取构造器*/
            Constructor con = clazz.getDeclaredConstructor(null);
            /*破封*/
            con.setAccessible(true);
            /*返回新实例*/
            return (Services) con.newInstance(null);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("文件没找到");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }
}

测试

public class TestForStaticFactory {

    public static void main(String[] args) {
        Provider provider = new ProviderImp();
        // 注册
        Services.registerProvider("ClientServer", provider);
        // 创建实例
        Service service = Services.newInstance("ClientServer");
        service.print();
    }
}

上面的代码,是服务提供者框架简单的实现,服务提供者框架是指一个系统:多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现,并且把他们从多个实现中解耦出来。
4.创建参数化类型实例时,代码会更加简洁

Map<String,List<String>> m = new Map<String, List<String>>();

上面的段代码中很冗长,经过下面的实现可以让代码更简洁

public static <K,V> HashMap<K,V> newInstance() {
	return new HashMap<K,V>();
}
//声明
Map <String,List<String>> m = HashMap.newInstance();

很显然声明变得更加简洁!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值