静态工厂方法 - 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,Present
和 Absent
。那么您可能希望有一个静态工厂方法来将可能为空的值转换为 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
}
我正在阅读 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,Present
和 Absent
。那么您可能希望有一个静态工厂方法来将可能为空的值转换为 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
}