工厂模式:对象创建的优雅解耦艺术

引言:对象创建的演变之路

在软件开发中,对象创建是最基础也是最关键的环节之一。随着系统复杂度增加,直接使用new关键字创建对象会导致:

客户端代码
具体实现类
依赖具体实现
代码耦合度高
难以扩展和维护

工厂模式正是为解决这类问题而生的设计模式。它通过将对象创建过程封装,实现了:

  • 创建逻辑与使用逻辑分离
  • 客户端与具体类解耦
  • 系统扩展性和灵活性提升

本文将深入剖析三种工厂模式(简单工厂、工厂方法、抽象工厂)的原理、实现及最佳实践。


一、工厂模式家族概览

1.1 三种工厂模式对比

模式类型 解决的核心问题 适用场景 复杂度
简单工厂 统一创建接口 对象种类有限且固定 ★☆☆
工厂方法 单一产品族扩展 需要动态扩展产品类型 ★★☆
抽象工厂 多产品族扩展 需要创建相关产品家族 ★★★

1.2 演进关系

简单工厂
工厂方法
抽象工厂

二、简单工厂模式:集中式对象工厂

2.1 模式定义

定义一个工厂类,根据传入参数的不同返回不同类的实例,被创建的实例通常具有共同的父类或接口。

2.2 UML类图

classDiagram
    class Client
    class SimpleFactory {
        +createProduct(String type) Product
    }
    interface Product {
        <>
        +operation()
    }
    class ConcreteProductA {
        +operation()
    }
    class ConcreteProductB {
        +operation()
    }
    
    Client --> SimpleFactory
    Client --> Product
    SimpleFactory ..> ConcreteProductA : 创建
    SimpleFactory ..> ConcreteProductB : 创建
    Product <|.. ConcreteProductA
    Product <|.. ConcreteProductB

2.3 代码实现

// 产品接口
public interface Shape {
    void draw();
}

// 具体产品
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}

public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}

// 简单工厂
public class ShapeFactory {
    public Shape createShape(String type) {
        if ("circle".equalsIgnoreCase(type)) {
            return new Circle();
        } else if ("rectangle".equalsIgnoreCase(type)) {
            return new Rectangle();
        }
        throw new IllegalArgumentException("未知图形类型: " + type);
    }
}

// 客户端
public class Client {
    public static void main(String[] args) {
        ShapeFactory factory = new ShapeFactory();
        
        Shape circle = factory.createShape("circle");
        circle.draw(); // 输出: 绘制圆形
        
        Shape rectangle = factory.createShape("rectangle");
        rectangle.draw(); // 输出: 绘制矩形
    }
}

2.4 优缺点分析

优点

  • 客户端与具体类解耦
  • 集中管理对象创建逻辑

缺点

  • 违反开闭原则(新增类型需修改工厂)
  • 工厂类职责过重

三、工厂方法模式:多态化对象工厂

3.1 模式定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

3.2 UML类图

classDiagram
    class Client
    interface Factory {
        <>
        +createProduct() Product
    }
    class ConcreteFactoryA {
        +createProduct() Product
    }
    class ConcreteFactoryB {
        +createProduct() Product
    }
    interface Product {
        <>
        +operation()
    }
    class ConcreteProductA {
        +operation()
    }
    class ConcreteProductB {
        +operation()
    }
    
    Client --> Factory
    Client --> Product
    Factory <|.. ConcreteFactoryA
    Factory <|.. ConcreteFactoryB
    Product <|.. ConcreteProductA
    Product <|.. ConcreteProductB
    ConcreteFactoryA ..> ConcreteProductA : 创建
    ConcreteFactoryB ..> ConcreteProductB : 创建

3.3 代码实现

// 数据库连接产品
public interface Connection {
    void connect();
    void executeQuery(String sql);
}

// MySQL连接
public class MySQLConnection implements Connection {
    @Override
    public void connect() {
        System.out.println("MySQL连接已建立");
    }
    
    @Override
    public void executeQuery(String sql) {
        System.out.println("执行MySQL查询: " + sql);
    }
}

// PostgreSQL连接
public class PostgreSQLConnection implements Connection {
    @Override
    public void connect() {
        System.out.println("PostgreSQL连接已建立");
    }
    
    @Override
    public void executeQuery(String sql) {
        System.out.println("执行PostgreSQL查询: " + sql);
    }
}

// 工厂接口
public interface ConnectionFactory {
    Connection createConnection();
}

// MySQL工厂
public class MySQLFactory implements ConnectionFactory {
    @Override
    public Connection createConnection() {
        return new MySQLConnection();
    }
}

// PostgreSQL工厂
public class PostgreSQLFactory implements ConnectionFactory {
    @Override
    public Connection createConnection() {
        return new PostgreSQLConnection();
    }
}

// 客户端
public class DatabaseClient {
    public void executeQuery(ConnectionFactory factory, String sql) {
        Connection conn = factory.createConnection();
        conn.connect();
        conn.executeQuery(sql);
    }
    
    public static void main(String[] args) {
        DatabaseClient client = new DatabaseClient();
        
        // 使用MySQL
        client.executeQuery(new MySQLFactory(), "SELECT * FROM users");
        
        // 使用PostgreSQL
        client.executeQuery(new PostgreSQLFactory(), "SELECT * FROM orders");
    }
}

3.4 模式变体

参数化工厂方法
public interface ConnectionFactory {
    Connection createConnection(String config);
}

public class DynamicDBFactory implements ConnectionFactory {
    @Override
    public Connection createConnection(String dbType) {
        switch (dbType.toLowerCase()) {
            case "mysql": return new MySQLConnection();
            case "postgresql": return new PostgreSQLConnection();
            default: throw new IllegalArgumentException("未知数据库类型");
        }
    }
}
带默认实现的工厂
public abstract class AbstractConnectionFactory implements ConnectionFactory {
    // 默认实现
    @Override
    public Connection createConnection() {
        return createConnection("default");
    }
    
    // 抽象方法
    public abstract Connection createConnection(String config);
}

四、抽象工厂模式:产品家族的创建者

4.1 模式定义

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

4.2 UML类图

classDiagram
    class Client
    interface AbstractFactory {
        <>
        +createButton() Button
        +createCheckbox() Checkbox
    }
    class WinFactory {
        +createButton() Button
        +createCheckbox() Checkbox
    }
    class MacFactory {
        +createButton() Button
        +createCheckbox() Checkbox
    }
    interface Button {
        <>
        +render()
    }
    interface Checkbox {
        <>
        +render()
    }
    class WinButton {
        +render()
    }
    class WinCheckbox {
        +render()
    }
    class MacButton {
        +render()
    }
    class MacCheckbox {
        +render()
    }
    
    Client --> AbstractFactory
    AbstractFactory <|.. WinFactory
    AbstractFactory <|.. MacFactory
    Button <|.. WinButton
    Button <|.. MacButton
    Checkbox <|.. WinCheckbox
    Checkbox <|.. MacCheckbox
    WinFactory ..> WinButton
    WinFactory ..> WinCheckbox
    MacFactory ..> MacButton
    MacFactory ..> MacCheckbox

4.3 代码实现

// 抽象产品:按钮
public interface Button {
    void render();
    void onClick();
}

// 抽象产品:复选框
public interface Checkbox {
    void render();
    void onCheck();
}

// Windows按钮
public class WinButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染Windows风格按钮");
    }
    
    @Override
    public void onClick() {
        System.out.println("Windows按钮点击事件处理");
    }
}

// Windows复选框
public class WinCheckbox implements Checkbox {
    @Override
    public void render() {
        System.out.println("渲染Windows风格复选框");
    }
    
    @Override
    public void onCheck() {
        System.out.println("Windows复选框选中事件处理");
    }
}

// Mac按钮
public class MacButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染macOS风格按钮");
    }
    
    @Override
    public void onClick() {
        System.out.println("macOS按钮点击事件处理");
    }
}

// Mac复选框
public class MacCheckbox implements Checkbox {
    @Override
    public void render() {
        System.out.println("渲染macOS风格复选框");
    }
    
    @Override
    public void onCheck() {
        System.out.println("macOS复选框选中事件处理");
    }
}

// 抽象工厂
public interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

// Windows工厂
public class WinFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WinButton();
    }
    
    @Override
    public Checkbox createCheckbox() {
        return new WinCheckbox();
    }
}

// Mac工厂
public class MacFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }
    
    @Override
    public Checkbox createCheckbox() {
        return new MacCheckbox();
    }
}

// 客户端
public class Application {
    private final Button button;
    private final Checkbox checkbox;
    
    public Application(GUIFactory factory) {
        button = factory.createButton();
        checkbox = factory.createCheckbox();
    }
    
    public void renderUI() {
        button.render();
        checkbox.render();
    }
    
    public void simulateUserActions() {
        button.onClick();
        checkbox.onCheck();
    }
    
    public static void main(String[] args) {
        // 根据配置决定使用哪个工厂
        GUIFactory factory;
        if (System.getProperty("os.name").toLowerCase().contains("win")) {
            factory = new WinFactory();
        } else {
            factory = new MacFactory();
        }
        
        Application app = new Application(factory);
        app.renderUI();
        app.simulateUserActions();
    }
}

4.4 模式扩展:支持新主题

// 新增Material Design主题
public class MaterialButton implements Button {
    // 实现略...
}

public class MaterialCheckbox implements Checkbox {
    // 实现略...
}

public class MaterialFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MaterialButton();
    }
    
    @Override
    public Checkbox createCheckbox() {
        return new MaterialCheckbox();
    }
}

// 动态切换主题
public class ThemeManager {
    private static GUIFactory currentFactory = new WinFactory();
    
    public static void setTheme(String theme) {
        switch (theme.toLowerCase()) {
            case "windows": currentFactory = new WinFactory(); break;
            case "mac": currentFactory = new MacFactory(); break;
            case "material": currentFactory = new MaterialFactory(); break;
            default: throw new IllegalArgumentException("未知主题");
        }
    }
    
    public static GUIFactory getFactory() {
        return currentFactory;
    }
}

五、工厂模式最佳实践

5.1 工厂模式选择指南

需要创建对象
对象类型是否固定
简单工厂
是否需要产品族
抽象工厂
工厂方法

5.2 性能优化策略

  1. 对象池技术

    public class ConnectionPoolFactory implements ConnectionFactory {
        private static final int POOL_SIZE = 10;
        private final Queue<Connection> pool = new LinkedList<>();
        
        public ConnectionPoolFactory() {
            for (int i = 0; i < POOL_SIZE; i++) {
                pool.add(new MySQLConnection());
            }
        }
        
        @Override
        public Connection createConnection() {
            if (pool.isEmpty()) {
                return new MySQLConnection();
            }
            return pool.poll();
        }
        
        public void releaseConnection(Connection conn) {
            if (pool.size() < POOL_SIZE) {
                pool.offer(conn);
            }
        }
    }
    
  2. 缓存重用

    public class ShapeFactory {
        private static final Map<String, Shape> cache = new HashMap<>();
        
        public Shape getShape(String type) {
            return cache.computeIfAbsent(type, t -> {
                switch (t.toLowerCase()) {
                    case "circle": return new Circle();
                    case "rectangle": return new Rectangle();
                    default: throw new IllegalArgumentException();
                }
            });
        }
    }
    

5.3 与依赖注入结合

// 使用Spring框架的依赖注入
@Configuration
public class FactoryConfig {
    @Bean
    @ConditionalOnProperty(name = "db.type", havingValue = "mysql")
    public ConnectionFactory mysqlFactory() {
        return new MySQLFactory();
    }
    
    @Bean
    @ConditionalOnProperty(name = "db.type", havingValue = "postgresql")
    public ConnectionFactory postgresFactory() {
        return new PostgreSQLFactory();
    }
}

// 客户端直接注入
@Service
public class DatabaseService {
    private final ConnectionFactory factory;
    
    @Autowired
    public DatabaseService(ConnectionFactory factory) {
        this.factory = factory;
    }
    
    public void executeQuery(String sql) {
        Connection conn = factory.createConnection();
        conn.executeQuery(sql);
    }
}

六、工厂模式在开源框架中的应用

6.1 Java集合框架

// Collections工厂方法
List<String> list = List.of("Java", "Python", "Go");
Set<Integer> set = Set.of(1, 2, 3);
Map<String, Integer> map = Map.of("A", 1, "B", 2);

// 内部实现(简化)
public interface List<E> {
    static <E> List<E> of(E... elements) {
        return new ImmutableCollections.ListN<>(elements);
    }
}

6.2 Spring框架

// BeanFactory是顶级工厂接口
public interface BeanFactory {
    Object getBean(String name) throws BeansException;
    <T> T getBean(Class<T> requiredType) throws BeansException;
}

// 应用场景
@Service
public class OrderService {
    @Autowired // 依赖注入相当于工厂
    private PaymentFactory paymentFactory;
    
    public void processOrder(Order order) {
        Payment payment = paymentFactory.create(order.getPaymentType());
        payment.process(order.getAmount());
    }
}

6.3 Log4j2日志框架

// 日志工厂
Logger logger = LogManager.getLogger(MyClass.class);

// 内部工厂实现(简化)
public final class LogManager {
    public static Logger getLogger(Class<?> clazz) {
        return getLogger(clazz.getName());
    }
    
    public static Logger getLogger(String name) {
        return ContextSelector.getContext().getLogger(name);
    }
}

七、工厂模式的反模式与陷阱

7.1 常见误用场景

  1. 过度设计简单对象创建

    // 反例:简单对象使用复杂工厂
    public class UserFactory {
        public User createUser(String name) {
            return new User(name); // 直接new就能解决
        }
    }
    
  2. 工厂类成为上帝对象

    // 反例:工厂类承担过多职责
    public class SuperFactory {
        public ProductA createA() { /* ... */ }
        public ProductB createB() { /* ... */ }
        public ProductC createC() { /* ... */ }
        public void validate() { /* ... */ }
        public void save() { /* ... */ } // 违反单一职责
    }
    

7.2 最佳规避实践

  1. 遵循单一职责原则

    工厂类
    只负责创建
    不包含业务逻辑
  2. 优先使用工厂方法

    // 正例:使用工厂方法而非简单工厂
    public interface ConnectionFactory {
        Connection create();
    }
    
    public class MySQLFactory implements ConnectionFactory {
        @Override
        public Connection create() {
            return new MySQLConnection();
        }
    }
    

八、工厂模式的现代演进

8.1 Lambda工厂

public interface ShapeFactory {
    Shape create();
}

// 使用Lambda表达式
ShapeFactory circleFactory = () -> new Circle();
Shape circle = circleFactory.create();

// 方法引用
ShapeFactory rectangleFactory = Rectangle::new;
Shape rectangle = rectangleFactory.create();

8.2 模块化工厂(Java 9+)

module com.example.shapes {
    exports com.example.shapes.api;
    provides com.example.shapes.api.ShapeFactory 
        with com.example.shapes.impl.CircleFactory;
}

// 服务加载
ServiceLoader<ShapeFactory> loader = 
    ServiceLoader.load(ShapeFactory.class);
ShapeFactory factory = loader.findFirst().orElseThrow();
Shape shape = factory.create();

8.3 响应式工厂

public interface ReactiveFactory<T> {
    Mono<T> createAsync();
}

public class DatabaseConnectionFactory implements ReactiveFactory<Connection> {
    @Override
    public Mono<Connection> createAsync() {
        return Mono.fromCallable(() -> {
            Connection conn = new MySQLConnection();
            conn.connect();
            return conn;
        }).subscribeOn(Schedulers.boundedElastic());
    }
}

九、总结:工厂模式的核心价值

工厂模式通过封装对象创建实现了:

解耦创建与使用
提高灵活性
统一创建接口
简化客户端
支持扩展
符合开闭原则

设计启示
不要直接创建对象,让工厂为你服务;不要依赖具体实现,依赖抽象接口

正如《设计模式》作者GoF所强调:

“工厂模式是对象创建的封装艺术,它让系统可以在不修改代码的情况下应对变化”


扩展思考

  1. 如何在分布式系统中实现工厂模式?
  2. 工厂模式如何与领域驱动设计(DDD)结合?
  3. 无工厂模式 vs 过度使用工厂模式的平衡点在哪里?

附录:工厂模式快速参考卡

模式 实现要点 应用场景
简单工厂 一个工厂类 + 条件判断 对象类型有限且固定
工厂方法 工厂接口 + 多个实现类 需要扩展产品类型
抽象工厂 抽象工厂接口 + 多个产品族 需要创建相关产品家族
静态工厂 工厂类的静态方法 工具类对象创建
Lambda工厂 函数式接口 + Lambda 简单对象的动态创建

工厂模式是构建灵活、可扩展系统的基石,在框架设计、业务解耦等场景中具有不可替代的价值

你可能感兴趣的:(设计模式)