静态工厂方法完全代替构造器 ?下

87 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 22 天,点击查看活动详情

前言

在前一天的分享中,我们讲了静态工厂的三个优点但是静态工厂的优点不仅于此,所以我将会讲完剩下的优点。

优点4静态工厂返回值是可以随参数的不一致而发生改变的

上面这句话的意思就是,你静态工厂可以根据参数的不同返回对应的东西。只要是声明对象的子类即可,而且这个返回对象的类可以随着版本变化。举一个例子就是EnumSet这个枚举类,他的构造器并不是公有的。但是有静态工厂可以有不一样的返回对象

EnumSet(Class<E>elementType, Enum<?>[] universe) {
    this.elementType = elementType;
    this.universe    = universe;
}

但是有静态工厂可以有不一样的返回对象,通过·不一样的Class类,来看这个枚举要返回什么样的类。其实我认为第四点和dida

public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
    Enum<?>[] universe = getUniverse(elementType);
    if (universe == null)
        throw new ClassCastException(elementType + " not an enum");

    if (universe.length <= 64)
        return new RegularEnumSet<>(elementType, universe);
    else
        return new JumboEnumSet<>(elementType, universe);
}

优点5方法对象返回的类,在编写的时候可以不存在

使用这种方法主要是在这种场景,有一个服务接口(这个是没有实现的)由提供者实现,然后有个注册API(Registration API)这是给提供者拿到该接口用的,最后来的服务访问api,这个给客户端使用的。

interface Service {
    // ...
}

// 服务提供者接口
interface Provider {
    Service newService();
}
public class Services {
    EnumSet enumSet  =new EnumSet<>()
    private static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>();//利用map,存储服务提供者
    public static void registerProvider(String name, Provider p1) {//注册服务提供者
        providers.put(name, p1);
    }
    // 服务访问API(使用静态工厂方法,返回值为接口类型)
    public static Service newInstance(String name) {//实例化服务
        Provider p = providers.get(name);
        return p.newService();//若存在注册的服务提供者,则可newService()提供服务
    }
}

像上面的代码就比较好的描述了这个优点,即使暂时没有实现,但是 之后根据传入的对象会实现不一样的。就比如说JDBC的实现,你就可以传入DrUid源,从而实现。