工厂模式(Factory Pattern)是软件开发中常用的创建型设计模式,其核心思想是将对象的创建过程封装起来,通过工厂类来统一管理对象的创建逻辑。这种模式分离了对象的创建和使用,使得客户端代码无需关心具体的创建细节,只需通过工厂获取所需对象即可。在 Java 开发中,工厂模式通过接口或抽象类定义产品和工厂的规范,具体实现类负责创建具体的产品实例,从而实现了代码的松耦合和高扩展性。
简单工厂模式又称为静态工厂模式,它不属于 23 种经典设计模式之一,但却是工厂模式中最基础的实现方式。简单工厂模式通过一个工厂类来根据传入的参数动态决定创建哪种具体产品实例。其特点是工厂类中包含了必要的逻辑判断,能够根据客户端的需求返回对应的产品实例,但缺点是当新增产品类型时,需要修改工厂类的代码,违反了开闭原则。
plaintext
客户端
↓
├─ 调用工厂类的静态方法
↓
简单工厂类(SimpleFactory)
↓
├─ 根据参数创建具体产品实例
↓
抽象产品(Product)
↓
具体产品A(ConcreteProductA)、具体产品B(ConcreteProductB)
(1)定义抽象产品接口或抽象类,声明产品的公共方法。
(2)创建具体产品类,实现抽象产品接口。
(3)设计简单工厂类,提供静态方法,根据传入的参数返回对应的具体产品实例。
java
public interface Product {
void display();
}
java
public class ConcreteProductA implements Product {
@Override
public void display() {
System.out.println("这是产品A");
}
}
public class ConcreteProductB implements Product {
@Override
public void display() {
System.out.println("这是产品B");
}
}
java
public class SimpleFactory {
public static Product createProduct(String productType) {
if ("A".equals(productType)) {
return new ConcreteProductA();
} else if ("B".equals(productType)) {
return new ConcreteProductB();
} else {
throw new IllegalArgumentException("无效的产品类型");
}
}
}
java
public class Client {
public static void main(String[] args) {
Product productA = SimpleFactory.createProduct("A");
productA.display(); // 输出:这是产品A
Product productB = SimpleFactory.createProduct("B");
productB.display(); // 输出:这是产品B
}
}
工厂方法模式是 23 种经典设计模式之一,它定义了一个创建产品对象的接口,但由具体工厂类决定创建哪种具体产品实例。工厂方法模式将简单工厂模式中集中的创建逻辑分散到各个具体工厂类中,每个具体工厂类负责创建一种具体产品,从而克服了简单工厂模式违反开闭原则的缺点。
plaintext
客户端
↓
├─ 调用抽象工厂接口
↓
抽象工厂(Factory)
↓
├─ 声明创建产品的抽象方法
↓
具体工厂A(ConcreteFactoryA)、具体工厂B(ConcreteFactoryB)
↓
├─ 实现创建具体产品的方法
↓
抽象产品(Product)
↓
具体产品A(ConcreteProductA)、具体产品B(ConcreteProductB)
(1)定义抽象产品接口,声明产品的公共方法。
(2)创建具体产品类,实现抽象产品接口。
(3)定义抽象工厂接口,声明创建产品的抽象方法。
(4)创建具体工厂类,实现抽象工厂接口,具体工厂类负责创建对应的具体产品实例。
java
public interface Product {
void display();
}
java
public class ConcreteProductA implements Product {
@Override
public void display() {
System.out.println("这是产品A");
}
}
public class ConcreteProductB implements Product {
@Override
public void display() {
System.out.println("这是产品B");
}
}
java
public interface Factory {
Product createProduct();
}
java
public class ConcreteFactoryA implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
public class ConcreteFactoryB implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
java
public class Client {
public static void main(String[] args) {
Factory factoryA = new ConcreteFactoryA();
Product productA = factoryA.createProduct();
productA.display(); // 输出:这是产品A
Factory factoryB = new ConcreteFactoryB();
Product productB = factoryB.createProduct();
productB.display(); // 输出:这是产品B
}
}
抽象工厂模式是工厂方法模式的扩展,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式用于创建属于不同产品族的产品对象,每个产品族中的产品具有某种共同的特性或功能,例如不同操作系统下的界面组件(Windows 和 Linux 下的按钮、文本框等)。
plaintext
客户端
↓
├─ 调用抽象工厂接口创建产品族
↓
抽象工厂(AbstractFactory)
↓
├─ 声明创建各产品等级结构中产品的方法
↓
具体工厂A(ConcreteFactoryA)、具体工厂B(ConcreteFactoryB)
↓
├─ 实现创建具体产品族的方法
↓
抽象产品A(AbstractProductA)、抽象产品B(AbstractProductB)
↓
具体产品A1(ConcreteProductA1)、具体产品A2(ConcreteProductA2)
具体产品B1(ConcreteProductB1)、具体产品B2(ConcreteProductB2)
(1)定义多个抽象产品接口,分别代表不同的产品等级结构。
(2)创建具体产品类,实现对应的抽象产品接口。
(3)定义抽象工厂接口,声明创建各个抽象产品的方法。
(4)创建具体工厂类,实现抽象工厂接口,具体工厂类负责创建属于同一产品族的多个产品实例。
java
public interface Button {
void display();
}
public class WindowsButton implements Button {
@Override
public void display() {
System.out.println("Windows按钮");
}
}
public class LinuxButton implements Button {
@Override
public void display() {
System.out.println("Linux按钮");
}
}
java
public interface TextBox {
void display();
}
public class WindowsTextBox implements TextBox {
@Override
public void display() {
System.out.println("Windows文本框");
}
}
public class LinuxTextBox implements TextBox {
@Override
public void display() {
System.out.println("Linux文本框");
}
}
java
public interface GUIFactory {
Button createButton();
TextBox createTextBox();
}
java
public class WindowsFactory implements GUIFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
@Override
public TextBox createTextBox() {
return new WindowsTextBox();
}
}
java
public class LinuxFactory implements GUIFactory {
@Override
public Button createButton() {
return new LinuxButton();
}
@Override
public TextBox createTextBox() {
return new LinuxTextBox();
}
}
java
public class Client {
public static void main(String[] args) {
GUIFactory factory = new WindowsFactory();
Button button = factory.createButton();
TextBox textBox = factory.createTextBox();
button.display(); // 输出:Windows按钮
textBox.display(); // 输出:Windows文本框
factory = new LinuxFactory();
button = factory.createButton();
textBox = factory.createTextBox();
button.display(); // 输出:Linux按钮
textBox.display(); // 输出:Linux文本框
}
}
特征 | 简单工厂模式 | 工厂方法模式 | 抽象工厂模式 |
---|---|---|---|
工厂类数量 | 一个工厂类 | 多个具体工厂类 | 多个具体工厂类 |
产品等级结构 | 单个产品等级结构 | 单个产品等级结构 | 多个产品等级结构 |
产品族 | 不支持 | 不支持 | 支持 |
开闭原则 | 违反 | 符合 | 部分符合(新增产品族符合,新增产品等级结构违反) |
复杂度 | 简单 | 中等 | 复杂 |
工厂模式通过抽象接口和具体实现的分离,使得新增产品类型或产品族时无需修改现有代码,只需添加新的具体类,符合开闭原则的 “对扩展开放,对修改关闭” 要求。
工厂方法模式和抽象工厂模式中,每个具体工厂类只负责创建一种或一类产品,符合单一职责原则,而简单工厂模式的工厂类职责较为集中,可能违反该原则。
工厂模式中,客户端依赖抽象产品接口和抽象工厂接口,而不是具体实现类,遵循了依赖倒置原则,降低了客户端与具体实现的耦合度。
具体产品类必须实现抽象产品接口的所有方法,具体工厂类必须实现抽象工厂接口的所有方法,确保了子类可以无缝替换父类,符合里氏替换原则。
在 Java 集合框架中,Collection
接口是抽象产品,ArrayList
、LinkedList
等是具体产品,而它们的创建过程虽然没有显式的工厂类,但通过构造方法或工厂方法(如Arrays.asList()
)实现了对象的创建,体现了工厂模式的思想。
Spring 框架中的 BeanFactory 和 ApplicationContext 就是工厂模式的典型应用。BeanFactory 作为抽象工厂,负责创建各种 Bean 对象,而具体的 Bean 创建逻辑由具体的工厂类(如 DefaultListableBeanFactory)实现。通过配置文件或注解,客户端可以轻松获取所需的 Bean 实例,无需关心对象的创建细节。
JDBC 中使用DriverManager
获取数据库连接的过程也应用了工厂模式。DriverManager
作为工厂类,根据不同的数据库 URL 创建对应的数据库连接(Connection
对象),客户端只需通过统一的接口操作数据库,无需了解具体数据库驱动的创建细节。
工厂模式是面向对象设计中处理对象创建的重要模式,它通过封装对象创建逻辑,提高了代码的可维护性、可扩展性和可复用性。无论是简单工厂模式的快速实现,还是工厂方法模式和抽象工厂模式的灵活扩展,都为软件开发提供了有效的解决方案。
随着软件开发的复杂化和模块化需求的增加,工厂模式在微服务、框架设计等领域的应用将更加广泛。结合 Java 8 的函数式接口和 Lambda 表达式,工厂模式的实现方式也在不断演进,例如使用Supplier
接口简化对象创建过程,提高代码的简洁性和灵活性。
总之,掌握工厂模式的核心思想和不同实现方式,能够帮助开发者在实际项目中更好地设计对象创建逻辑,提升系统的可维护性和扩展性,是 Java 开发中不可或缺的重要设计模式之一。