美文网首页
Effective Java学习笔记 (一)考略使用静态工厂方法

Effective Java学习笔记 (一)考略使用静态工厂方法

作者: 猪_队友 | 来源:发表于2018-08-12 18:27 被阅读92次

    优势:

    1、 他们有名称

    通过名称可以更清楚的知道这个方法的作用。
    比如ImageLoader.loadIconImage(String url); 和 ImageLoader(String url,String type)、ImageLoader(String url)
    用户永远记不住参数类型顺序上的有所不同,也记不住应该用哪一个构造器,所以会常常调用错误构造器。所以静态工厂方法有名称,可以不受这个的影响。

    2、不必每次调用他们的时候都创建一个新的对象

    这个可以使不可变类可以使用预先构件好的实例。进行重复使用。参考单例模式。

    3、他们可以返回原返回类型的任何子类型的对象

    这样可以让我们在选择对象的类的时候有了更大的灵活性。
    这种灵活性的一种应用是:API可以返回对象,同时又不会使对象的类变成共有的。以这样的方式隐藏实现类会使API变得非常简单。

    下面是一个简单的实现,包含一个服务提供者接口和一个默认提供者

    //服务接口
    public interface Service{
    }
    //服务提供者接口
    public interface Provider{
    //这个方法提供服务
    Service newService();
    }
    
    public class Service{
    //私有构造方法
    private Service(){}
    //用来存放不同的服务提供者 根据名字区分
    private static final Map<String,Provider> providers =
     new  ConcurrentHashMap<String,Providers>();
    //默认的服务提供者的名字
    public static final String DEFAULT_PROVIDER_NAME = "<def>";
    //默认注册 默认名称的服务提供者
    public static void registerDefaultProvider(Provider p){
    registerProvider(DEFAULT_PROVIDER_NAME,p);
    }
    //把自己创建名称的服务提供者加入这个Map里
    public static void registerDefaultProvider(String name,Provider p){
    providers.put(name,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();
    
    }
    }
    

    这个是我们常见的服务提供者控件的简化版本。
    我们可以看到通过我们不同的静态工厂方法,使构造方法私有,隐藏了实现类,只需要实现类实现这个接口就可以了,比如这个Provider,对于实现类我们是不可预料的,所以大大增加了灵活性。

    4、再创建参数化类型实例的时候,他们使代码变得更加简洁

    比如这个:

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

    随着类型参数的增加,会越来越长,越来越复杂,让人很是痛苦。那我们用一下静态工厂方法。

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

    这样是不是很爽啊。代替了繁琐的声明。

    缺点:

    1、类如果不含共有的或者受保护的构造器,就不能被子类化

    对于共有的静态工厂所返回的非共有类也是如此。
    例如:要想将Collections FrameWork中的任何方便的实现类子类化,这是不可能的。但是也因祸得福,鼓励程序员使用复合(composition),而不是继承。

    2、他们与其他的静态方法没有任何区别

    小结:

    静态工厂方法和公有构造器都有各自的好处,通常下静态工厂会更加合适。因此急切第一反应就是提供公有构造器,而要先考虑静态工厂是否可以用。

    相关文章

      网友评论

          本文标题:Effective Java学习笔记 (一)考略使用静态工厂方法

          本文链接:https://www.haomeiwen.com/subject/omisbftx.html