Java 中的工厂模式:简化对象创建
大约 3 分钟
工厂设计模式的意图
Java 中的工厂设计模式是一种创建型模式,它定义了一个用于创建对象的接口,但允许子类更改将要创建的对象类型。这种模式促进了代码库的灵活性和可扩展性。
工厂模式的详细解释,包括现实世界的例子
现实世界的例子
想象一下,在一家面包店里,使用工厂设计模式制作不同种类的蛋糕。面包店的
CakeFactory
处理创建过程,允许轻松添加新的蛋糕类型,而无需更改核心蛋糕制作过程。CakeFactory
可以生产各种类型的蛋糕,例如巧克力蛋糕、香草蛋糕和草莓蛋糕。面包店员工无需手动选择配料并遵循每种蛋糕类型的特定食谱,而是使用CakeFactory
来处理此过程。顾客只需要求一种蛋糕类型,CakeFactory
就会确定要使用的合适配料和食谱,然后创建特定类型的蛋糕。这种设置允许面包店轻松添加新的蛋糕类型,而无需修改核心蛋糕制作过程,从而提高灵活性和可扩展性。
维基百科说
工厂是一个用于创建其他对象的物体 - 正式来说,工厂是一个返回不同原型或类的对象的函数或方法。
Java 中工厂模式的编程示例
想象一下,一个炼金术士要制造硬币。炼金术士必须能够制造金币和铜币,并且必须能够在它们之间切换,而无需修改现有的源代码。工厂模式通过提供一个静态构造方法来实现这一点,该方法可以与相关参数一起调用。
在 Java 中,您可以通过定义一个接口 Coin
及其实现 GoldCoin
和 CopperCoin
来实现工厂模式。CoinFactory
类提供了一个静态方法 getCoin
来创建基于类型的硬币对象。
public interface Coin {
String getDescription();
}
public class GoldCoin implements Coin {
static final String DESCRIPTION = "This is a gold coin.";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class CopperCoin implements Coin {
static final String DESCRIPTION = "This is a copper coin.";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
下面的枚举表示我们支持的硬币类型(GoldCoin
和 CopperCoin
)。
@RequiredArgsConstructor
@Getter
public enum CoinType {
COPPER(CopperCoin::new),
GOLD(GoldCoin::new);
private final Supplier<Coin> constructor;
}
然后我们有静态方法 getCoin
来创建封装在工厂类 CoinFactory
中的硬币对象。
public class CoinFactory {
public static Coin getCoin(CoinType type) {
return type.getConstructor().get();
}
}
现在,在客户端代码中,我们可以使用工厂类生成各种类型的硬币。
public static void main(String[] args) {
LOGGER.info("The alchemist begins his work.");
var coin1 = CoinFactory.getCoin(CoinType.COPPER);
var coin2 = CoinFactory.getCoin(CoinType.GOLD);
LOGGER.info(coin1.getDescription());
LOGGER.info(coin2.getDescription());
}
程序输出
06:19:53.530 [main] INFO com.iluwatar.factory.App -- The alchemist begins his work.
06:19:53.533 [main] INFO com.iluwatar.factory.App -- This is a copper coin.
06:19:53.533 [main] INFO com.iluwatar.factory.App -- This is a gold coin.
何时在 Java 中使用工厂模式
- 当类事先不知道它需要创建的对象的精确类型和依赖关系时,在 Java 中使用工厂设计模式。
- 当一个方法返回多个可能的类之一(这些类共享一个共同的超类)并且想要封装要创建哪个对象的逻辑时。
- 这种模式通常在设计框架或库时使用,以提供最佳的灵活性和与具体类类型的隔离。
Java 中工厂模式的实际应用
- java.util.Calendar#getInstance()
- java.util.ResourceBundle#getBundle()
- java.text.NumberFormat#getInstance()
- java.nio.charset.Charset#forName()
- java.net.URLStreamHandlerFactory#createURLStreamHandler(String)(根据协议返回不同的单例对象)
- java.util.EnumSet#of()
- javax.xml.bind.JAXBContext#createMarshaller() 及其他类似方法。
- JavaFX 使用工厂模式来创建针对用户环境特性的各种 UI 控件。
工厂模式的优点和权衡
优点
- 在 Java 应用程序中实现工厂模式可减少实现与其使用的类之间的耦合。
- 支持 开闭原则,因为系统可以引入新的类型而无需更改现有代码。
权衡
- 由于引入了多个额外的类,代码可能会变得更加复杂。
- 如果对象创建的底层复杂度很低或不必要,过度使用可能会使代码的可读性降低。
相关的 Java 设计模式
- 抽象工厂:可以被认为是一种处理产品组的工厂。
- 单例:通常与工厂一起使用,以确保类只有一个实例。
- 建造者:将复杂对象的构建与其表示分离,类似于工厂如何管理实例化。
- 工厂工具包:是一个具有独立的建造者和工厂接口的不可变内容工厂。