【设计模式】工厂模式
工厂方法模式深度解析:对象创建的优雅之道
一、工厂方法模式核心概念
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,定义了一个创建对象的接口,但让子类决定实例化哪一个类。它将对象的实例化过程推迟到子类,实现了创建者与具体产品的解耦。
核心价值:
- ✅ 解耦创建逻辑:将对象创建代码与使用代码分离
- ✅ 扩展性强:新增产品类型只需添加新工厂
- ✅ 符合开闭原则:不修改已有代码即可扩展系统
- ✅ 统一创建入口:提供一致的实例化接口
二、为什么需要工厂方法模式?
当遇到以下场景时,工厂方法模式是理想选择:
- 创建逻辑复杂:对象创建需要多步初始化或条件判断
- 系统需要扩展:预期未来会新增产品类型
- 依赖抽象而非实现:客户端不应依赖具体类
- 资源统一管理:如数据库连接、线程池等资源的创建
graph LR
Client --> Creator[创建者接口]
Creator --> ConcreteCreatorA[具体创建者A]
Creator --> ConcreteCreatorB[具体创建者B]
ConcreteCreatorA --> ProductA[具体产品A]
ConcreteCreatorB --> ProductB[具体产品B]
三、工厂方法模式实现方式大全
1. 基础实现(标准模式)
// 产品接口
interface Transport {
void deliver();
}
// 具体产品
class Truck implements Transport {
@Override
public void deliver() {
System.out.println("陆路运输:卡车送货");
}
}
class Ship implements Transport {
@Override
public void deliver() {
System.out.println("海运:货轮送货");
}
}
// 创建者接口
interface Logistics {
Transport createTransport();
}
// 具体创建者
class RoadLogistics implements Logistics {
@Override
public Transport createTransport() {
return new Truck();
}
}
class SeaLogistics implements Logistics {
@Override
public Transport createTransport() {
return new Ship();
}
}
// 客户端使用
public class Client {
public static void main(String[] args) {
Logistics logistics = new RoadLogistics();
Transport transport = logistics.createTransport();
transport.deliver(); // 输出:陆路运输:卡车送货
}
}
2. 参数化工厂方法
enum TransportType { TRUCK, SHIP, AIRPLANE }
abstract class Logistics {
// 参数化工厂方法
public Transport createTransport(TransportType type) {
switch (type) {
case TRUCK: return new Truck();
case SHIP: return new Ship();
case AIRPLANE: return new Airplane();
default: throw new IllegalArgumentException("未知运输类型");
}
}
// 业务方法
public void planDelivery() {
Transport t = createTransport(getTransportType());
t.deliver();
}
// 抽象方法由子类实现
protected abstract TransportType getTransportType();
}
// 具体创建者
class FastLogistics extends Logistics {
@Override
protected TransportType getTransportType() {
return TransportType.AIRPLANE;
}
}
3. 使用Lambda表达式(Java 8+)
interface TransportFactory {
Transport create();
}
public class LambdaFactory {
public static void main(String[] args) {
// 使用Lambda实现工厂
TransportFactory truckFactory = Truck::new;
TransportFactory shipFactory = Ship::new;
Transport t1 = truckFactory.create();
Transport t2 = shipFactory.create();
t1.deliver(); // 输出:陆路运输:卡车送货
t2.deliver(); // 输出:海运:货轮送货
}
}
4. 带初始化参数的工厂
interface TransportFactory {
Transport create(String model, double capacity);
}
class TruckFactory implements TransportFactory {
@Override
public Transport create(String model, double capacity) {
Truck truck = new Truck();
truck.setModel(model);
truck.setCapacity(capacity);
return truck;
}
}
// 客户端使用
Transport heavyTruck = new TruckFactory()
.create("Heavy-Duty", 20.0);
四、工厂方法模式原理深度剖析
🔍 核心机制:延迟实例化与多态绑定
工厂方法模式通过两个关键特性实现解耦:
- 延迟实例化:创建者类不直接实例化产品,而是通过工厂方法
- 多态绑定:运行时根据具体创建者类型决定产品类型
public abstract class Creator {
// 工厂方法(核心)
public abstract Product factoryMethod();
public void businessLogic() {
// 使用工厂方法创建产品
Product product = factoryMethod();
product.operation();
}
}
✨ 设计优势解析
| 特性 | 传统创建方式 | 工厂方法模式 |
|---|---|---|
| 耦合度 | 客户端直接依赖具体类 | 客户端仅依赖抽象接口 |
| 扩展性 | 修改客户端代码才能添加新产品 | 只需新增具体创建者 |
| 可测试性 | 难模拟具体产品 | 易注入模拟产品 |
| 代码复用 | 创建逻辑重复 | 创建逻辑封装在工厂中 |
五、工厂方法模式防护措施
1. 防止无效产品创建
public abstract class Logistics {
public Transport createTransport() {
Transport t = createTransportInternal();
if (!t.validate()) {
throw new IllegalStateException("无效的运输工具");
}
return t;
}
protected abstract Transport createTransportInternal();
}
2. 工厂方法安全扩展
public final class SecureLogisticsFactory {
// 防止子类覆盖核心逻辑
public final Transport createSecureTransport() {
Transport t = createTransport();
enableSecurityFeatures(t);
return t;
}
// 工厂方法可被覆盖
protected Transport createTransport() {
return new StandardTruck();
}
private void enableSecurityFeatures(Transport t) {
// 添加安全特性
}
}
六、模式对比与最佳实践
工厂方法 vs 简单工厂
| 特性 | 简单工厂 | 工厂方法 |
|---|---|---|
| 创建逻辑位置 | 集中在一个工厂类 | 分散在子类中 |
| 开闭原则 | 违反(修改工厂添加新产品) | 符合(新增子类即可) |
| 复杂度 | 简单 | 中等 |
| 适用场景 | 产品类型固定的小型系统 | 需要扩展的中大型系统 |
工厂方法 vs 抽象工厂
| 特性 | 工厂方法 | 抽象工厂 |
|---|---|---|
| 创建目标 | 单一产品 | 产品族 |
| 方法数量 | 一个工厂方法 | 多个工厂方法 |
| 层次结构 | 类级别 | 系统级别 |
| 典型场景 | 创建单一对象 | 创建相关对象集合 |
最佳实践建议:
- 优先选择工厂方法:当系统预期需要扩展新产品时
- 结合使用模式:工厂方法常作为抽象工厂的组成部分
- 使用Lambda简化:Java 8+项目可用Lambda表达式简化工厂实现
- 避免过度设计:简单场景直接使用
new更合适
七、典型应用场景
- 跨平台UI开发
// 创建者接口
interface GUIFactory {
Button createButton();
Menu createMenu();
}
// Windows实现
class WinFactory implements GUIFactory {
public Button createButton() { return new WinButton(); }
public Menu createMenu() { return new WinMenu(); }
}
// Mac实现
class MacFactory implements GUIFactory {
public Button createButton() { return new MacButton(); }
public Menu createMenu() { return new MacMenu(); }
}
- 数据库连接管理
interface ConnectionFactory {
Connection createConnection();
}
class MySQLConnectionFactory implements ConnectionFactory {
public Connection createConnection() {
return DriverManager.getConnection(MySQL_URL);
}
}
class OracleConnectionFactory implements ConnectionFactory {
public Connection createConnection() {
return DriverManager.getConnection(Oracle_URL);
}
}
- 支付网关集成
interface PaymentProcessorFactory {
PaymentProcessor createProcessor();
}
class PayPalFactory implements PaymentProcessorFactory {
public PaymentProcessor createProcessor() {
return new PayPalAdapter();
}
}
class StripeFactory implements PaymentProcessorFactory {
public PaymentProcessor createProcessor() {
return new StripeAdapter();
}
}
八、总结
工厂方法模式通过将对象创建过程抽象化,提供了高度灵活的系统架构:
-
核心优势:
- 创建逻辑与业务逻辑分离
- 符合开闭原则,易于扩展
- 增强代码可读性和可维护性
-
实现要点:
- 工厂方法使用继承实现多态创建
- 具体创建者决定实例化哪个具体产品
- 客户端仅依赖抽象接口
-
应用警示:
- 避免创建不必要的工厂层次
- 简单场景直接实例化更高效
- 注意工厂方法的线程安全性
graph TD
A[需要创建对象?] --> B{创建逻辑是否复杂?}
B -->|简单| C[直接使用 new 运算符]
B -->|复杂| D{系统是否需要扩展?}
D -->|是| E[使用工厂方法模式]
D -->|否| F[使用简单工厂]
E --> G[定义创建者接口和产品接口]
G --> H[实现具体创建者和产品]
工厂方法模式是应对对象创建复杂性和系统扩展需求的利器。当系统需要灵活支持新产品类型时,该模式能显著降低代码耦合度,提高架构的可维护性。正确应用工厂方法模式,可以使你的代码在面对变化时更加从容稳定。
❤️ 如果你喜欢这篇文章,请点赞支持! 👍 同时欢迎关注我的博客,获取更多精彩内容!
本文来自博客园,作者:佛祖让我来巡山,转载请注明原文链接:https://www.cnblogs.com/sun-10387834/p/18950253

浙公网安备 33010602011771号