Java设计模式之工厂模式
1. 引言
工厂模式(Factory Pattern)是创建型设计模式之一,旨在提供一个创建对象的接口,而不是直接通过 new
关键字来实例化对象。工厂模式在提高代码的可维护性、可扩展性和灵活性方面具有显著优势。
更多设计模式请参考:
Java 中的 23 种设计模式详解
2. 工厂模式的分类
工厂模式主要分为三类:
- 简单工厂模式(Simple Factory)
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
2.1 简单工厂模式
概念
简单工厂模式通过一个静态方法,根据传入的参数,返回不同类型的对象。尽管这种模式在严格意义上不被认为是一种设计模式,但它是其他工厂模式的基础。
优点:
- 客户端不需要知道具体产品类的类名,只需要知道一个参数即可创建产品实例,降低了客户端与具体产品类的耦合。
缺点:
- 增加新的产品时需要修改工厂类,违反了开放-关闭原则(OCP)。
- 简单工厂模式中的工厂类集中了所有产品的创建逻辑,职责过重,不利于代码维护。
使用场景
- 当工厂类负责创建的对象比较少时。
- 客户端只需知道传入工厂类的参数即可创建对象时。
实现示例
假设我们有一个产品接口和几种具体产品:
java
// 产品接口
public interface Product {
void use();
}
// 具体产品A
public class ProductA implements Product {
@Override
public void use() {
System.out.println("Using Product A");
}
}
// 具体产品B
public class ProductB implements Product {
@Override
public void use() {
System.out.println("Using Product B");
}
}
现在我们创建一个简单工厂类:
java
public class SimpleFactory {
// 静态方法,根据传入的参数创建不同的产品对象
public static Product createProduct(String type) {
switch (type) {
case "A":
return new ProductA();
case "B":
return new ProductB();
default:
throw new IllegalArgumentException("Unknown product type");
}
}
}
使用示例:
java
public class Main {
public static void main(String[] args) {
// 创建产品A
Product productA = SimpleFactory.createProduct("A");
productA.use();
// 创建产品B
Product productB = SimpleFactory.createProduct("B");
productB.use();
}
}
2.2 工厂方法模式
概念
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式让类的实例化推迟到子类。
优点:
- 遵循开放-关闭原则,新增产品时只需增加相应的具体产品类和具体工厂类。
- 遵循单一职责原则,每个具体工厂类只负责创建对应的产品。
缺点:
- 增加了系统的复杂性,增加了类的数量。
使用场景
- 一个类不知道它所需要的对象的类时。
- 一个类通过其子类来指定创建哪个对象时。
- 将创建对象的职责委托给多个工厂子类中的某一个,客户端在使用时通过具体工厂类来创建对象。
实现示例
java
// 工厂接口
public interface Factory {
Product createProduct();
}
// 具体工厂A
public class FactoryA implements Factory {
@Override
public Product createProduct() {
return new ProductA();
}
}
// 具体工厂B
public class FactoryB implements Factory {
@Override
public Product createProduct() {
return new ProductB();
}
}
使用示例:
java
public class Main {
public static void main(String[] args) {
// 创建具体工厂A
Factory factoryA = new FactoryA();
// 通过工厂A创建产品A
Product productA = factoryA.createProduct();
productA.use();
// 创建具体工厂B
Factory factoryB = new FactoryB();
// 通过工厂B创建产品B
Product productB = factoryB.createProduct();
productB.use();
}
}
2.3 抽象工厂模式
概念
抽象工厂模式提供一个创建一系列相关或依赖对象的接口,而无需指定它们的具体类。抽象工厂模式使得系统能够独立于这些对象的创建过程。
优点:
- 分离了具体类的生成,符合开放-关闭原则。
- 可以在不修改已有代码的情况下增加新的产品系列。
- 通过一个工厂创建多个相关的产品对象,保证产品对象的一致性。
缺点:
- 增加了系统的复杂性,增加了类的数量。
使用场景
- 一个系统需要独立于其产品创建、组合和表示时。
- 一个系统需要配置多个产品系列中的一个时。
- 需要强调一系列相关的产品对象一起使用时。
实现示例
假设我们有两个系列的产品,A系列和B系列,每个系列都有产品1和产品2:
java
// 抽象产品1
public interface Product1 {
void use();
}
// 抽象产品2
public interface Product2 {
void use();
}
// 具体产品A1
public class ProductA1 implements Product1 {
@Override
public void use() {
System.out.println("Using Product A1");
}
}
// 具体产品A2
public class ProductA2 implements Product2 {
@Override
public void use() {
System.out.println("Using Product A2");
}
}
// 具体产品B1
public class ProductB1 implements Product1 {
@Override
public void use() {
System.out.println("Using Product B1");
}
}
// 具体产品B2
public class ProductB2 implements Product2 {
@Override
public void use() {
System.out.println("Using Product B2");
}
}
现在我们创建抽象工厂接口及其具体工厂:
java
// 抽象工厂
public interface AbstractFactory {
Product1 createProduct1();
Product2 createProduct2();
}
// 具体工厂A
public class FactoryA implements AbstractFactory {
@Override
public Product1 createProduct1() {
return new ProductA1();
}
@Override
public Product2 createProduct2() {
return new ProductA2();
}
}
// 具体工厂B
public class FactoryB implements AbstractFactory {
@Override
public Product1 createProduct1() {
return new ProductB1();
}
@Override
public Product2 createProduct2() {
return new ProductB2();
}
}
使用示例:
java
public class Main {
public static void main(String[] args) {
// 创建具体工厂A
AbstractFactory factoryA = new FactoryA();
// 通过工厂A创建产品A1和A2
Product1 productA1 = factoryA.createProduct1();
Product2 productA2 = factoryA.createProduct2();
productA1.use();
productA2.use();
// 创建具体工厂B
AbstractFactory factoryB = new FactoryB();
// 通过工厂B创建产品B1和B2
Product1 productB1 = factoryB.createProduct1();
Product2 productB2 = factoryB.createProduct2();
productB1.use();
productB2.use();
}
}
3. 总结
工厂模式是非常有用的设计模式,通过将对象的创建过程封装起来,提供了一种灵活且可扩展的解决方案。在实际开发中,根据具体的需求选择合适的工厂模式,可以显著提高代码的维护性和可扩展性。
简单工厂模式
- 适用场景: 对象类型较少时。
- 优点: 客户端只需知道传入参数即可创建对象。
- 缺点: 新增产品需要修改工厂类,违反开放-关闭原则。
工厂方法模式
- 适用场景: 对象类型较多且需要频繁扩展时。
- 优点: 遵循开放-关闭原则和单一职责原则。
- 缺点: 增加了系统的复杂性和类的数量。
抽象工厂模式
- 适用场景: 需要创建一系列相关或依赖对象时。
- 优点: 分离了具体类的生成,保证产品对象的一致性。
- 缺点: 增加了系统的复杂性和类的数量。
理解并熟练应用工厂模式,是成为优秀Java开发者的重要一环。