静态工厂方法 - return 任何子类型

Static Factory Methods - return any subtype

我正在阅读 Effective Java 一书,Joshua Bloch 在第 2 章中说:

A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type.

我不明白如何在实践中使用这个概念?

有人能给我举个例子吗?

例如,假设您想编写自己的选项类型。你可以有一个接口 MyOption,其中有两个实现 classes,PresentAbsent。那么您可能希望有一个静态工厂方法来将可能为空的值转换为 MyOption 对象。它可能看起来像这样:

public static <T> MyOption<T> ofNullable(T value) {
    if(value == null) {
        return new Absent<>();
    } else {
        return new Present<>(value);
    }
}

请注意,静态工厂方法 MyOption.ofNullable(value) returns 一个不同的 class 对象取决于参数的值。编写构造函数使得 new MyOption<>(value) 具有相同的行为是不可能的。

1.对对象创建的客户端隐藏(更好的封装)

这里有一个所谓的"Simple Factory"(a.k.a.参数化工厂)的例子:

public class UserFactory {

    public static User newUser(UserEnum type){
        switch (type){
            case ADMIN: return new Admin();
            case STAFF: return new StaffMember();
            case CLIENT: return new Client();
            default:
                throw new IllegalArgumentException("Unsupported user. You input: " + type);
        } 
    }
}

将对象创建封装到静态工厂中的要点是用户不知道(也不关心)对象是如何创建的:

// client code - give me an admin object, 
// don't care about the inner details of how it gets constructed
User admin = UserFactory.newUser(ADMIN); 

2。在不破坏客户端代码的情况下更换实现的灵活性

考虑这个静态工厂方法:

// swap out with LinkedList later if you like, 
// it won't break the 100 places that invoke this method
public static List<String> getMyList(){
    return new ArrayList<>(); 
}

不喜欢任何标准的列表实现方式,稍后您会创建自己的列表实现方式吗?

public class MyMuchBetterList<E> extends AbstractList<E> implements List<E> {

    // implementation
}

没问题,您仍然可以在静态工厂内部交换 而不影响 那些使用 getMyList 的人:

public static List<String> getMyList(){
        return new MyMuchBetterList<>(); // compiles and works, subtype of list
    }