工厂模式是将创建对象和使用对象分离,并且客户端总是引用抽象产品和抽象工厂。
比如实现一个字段串转为Number,可以定义如下:
public class NumberFactoryImpl implements NumberFactory {
public Number parse(String s) {
return new BigDecimal(s);
}
}
那么客户端如何创建NumberFactoryImpl
呢?通常我们会在接口Factory
中定义一个静态方法getFactory()
来返回真正的子类:
public interface NumberFactory {
// 创建方法:
Number parse(String s);
// 获取工厂实例:
static NumberFactory getFactory() {
return impl;
}
static NumberFactory impl = new NumberFactoryImpl();
}
在客户端中,我们只需要和工厂接口NumberFactory
以及抽象产品Number
打交道:
NumberFactory factory = NumberFactory.getFactory();
Number result = factory.parse("123.456");
调用方可以完全忽略真正的工厂NumberFactoryImpl
和实际的产品BigDecimal
,这样做的好处是允许创建产品的代码独立地变换,而不会影响到调用方。
静态工厂方法广泛地应用在Java标准库中。例如:
List<String> list = List.of("A", "B", "C");
Integer n = Integer.valueOf(100);
public final class Integer {
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
...
}
它的好处在于,valueOf()
内部可能会使用new
创建一个新的Integer
实例,但也可能直接返回一个缓存的Integer
实例。对于调用方来说,没必要知道Integer
创建的细节。