Java工厂模式原理详解

Java工厂模式原理详解

工厂模式是Java中最常用的设计模式之一,它属于创建型模式,主要解决对象创建的问题,将对象的创建与使用分离,提高代码的灵活性和可维护性。


一、工厂模式概述

为什么需要工厂模式?

​没有工厂模式的问题:​

// 客户端直接创建具体对象 - 紧耦合
public class Client {
    public void process() {
        // 直接依赖具体实现类
        Car car = new BenzCar();  // 如果要换车型,需要修改代码
        car.drive();
        
        // 或者
        Car car2 = new BMWCar();  // 还是需要修改代码
        car2.drive();
    }
}

​工厂模式的优势:​

  • ​解耦​​:客户端不关心对象的创建细节

  • ​可扩展​​:新增产品类型时不需要修改客户端代码

  • ​统一管理​​:集中管理对象的创建逻辑

  • ​符合开闭原则​​:对扩展开放,对修改关闭


二、简单工厂模式(静态工厂模式)

1. 基本结构

客户端 → 工厂类 → 具体产品

2. 代码实现

// 1. 产品接口
public interface Car {
    void drive();
    String getInfo();
}

// 2. 具体产品实现
public class BenzCar implements Car {
    @Override
    public void drive() {
        System.out.println("奔驰车在行驶...");
    }
    
    @Override
    public String getInfo() {
        return "奔驰汽车";
    }
}

public class BMWCar implements Car {
    @Override
    public void drive() {
        System.out.println("宝马车在行驶...");
    }
    
    @Override
    public String getInfo() {
        return "宝马汽车";
    }
}

public class AudiCar implements Car {
    @Override
    public void drive() {
        System.out.println("奥迪车在行驶...");
    }
    
    @Override
    public String getInfo() {
        return "奥迪汽车";
    }
}

// 3. 简单工厂类
public class SimpleCarFactory {
    /**
     * 静态工厂方法 - 根据类型创建对象
     */
    public static Car createCar(String type) {
        if (type == null) {
            return null;
        }
        
        switch (type.toLowerCase()) {
            case "benz":
                return new BenzCar();
            case "bmw":
                return new BMWCar();
            case "audi":
                return new AudiCar();
            default:
                throw new IllegalArgumentException("不支持的汽车类型: " + type);
        }
    }
    
    /**
     * 方法重载 - 根据枚举创建对象
     */
    public static Car createCar(CarType carType) {
        if (carType == null) {
            return null;
        }
        
        switch (carType) {
            case BENZ:
                return new BenzCar();
            case BMW:
                return new BMWCar();
            case AUDI:
                return new AudiCar();
            default:
                throw new IllegalArgumentException("不支持的汽车类型: " + carType);
        }
    }
}

// 汽车类型枚举
public enum CarType {
    BENZ, BMW, AUDI
}

// 4. 客户端使用
public class Client {
    public static void main(String[] args) {
        // 使用简单工厂创建对象
        Car benz = SimpleCarFactory.createCar("benz");
        Car bmw = SimpleCarFactory.createCar(CarType.BMW);
        
        benz.drive();  // 输出: 奔驰车在行驶...
        bmw.drive();   // 输出: 宝马车在行驶...
        
        System.out.println(benz.getInfo());  // 输出: 奔驰汽车
        System.out.println(bmw.getInfo());   // 输出: 宝马汽车
    }
}

3. 优缺点分析

​优点:​

  • 客户端与具体实现解耦

  • 代码结构清晰

​缺点:​

  • 违反开闭原则(新增产品需要修改工厂类)

  • 工厂类职责过重


三、工厂方法模式(Factory Method Pattern)

1. 核心思想

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

2. 类图结构

抽象创建者(Creator)
    ↑
具体创建者(Concrete Creator) → 具体产品(Concrete Product)

3. 代码实现

// 1. 产品接口
public interface Logger {
    void log(String message);
    void error(String message);
    void warn(String message);
}

// 2. 具体产品
public class FileLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("文件日志 - INFO: " + message);
    }
    
    @Override
    public void error(String message) {
        System.out.println("文件日志 - ERROR: " + message);
    }
    
    @Override
    public void warn(String message) {
        System.out.println("文件日志 - WARN: " + message);
    }
}

public class DatabaseLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("数据库日志 - INFO: " + message);
    }
    
    @Override
    public void error(String message) {
        System.out.println("数据库日志 - ERROR: " + message);
    }
    
    @Override
    public void warn(String message) {
        System.out.println("数据库日志 - WARN: " + message);
    }
}

public class ConsoleLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("控制台日志 - INFO: " + message);
    }
    
    @Override
    public void error(String message) {
        System.out.println("控制台日志 - ERROR: " + message);
    }
    
    @Override
    public void warn(String message) {
        System.out.println("控制台日志 - WARN: " + message);
    }
}

// 3. 抽象创建者
public abstract class LoggerFactory {
    /**
     * 工厂方法 - 由子类实现具体创建逻辑
     */
    public abstract Logger createLogger();
    
    /**
     * 业务方法 - 使用工厂方法创建的产品
     */
    public void log(String message) {
        Logger logger = createLogger();
        logger.log(message);
    }
    
    public void error(String message) {
        Logger logger = createLogger();
        logger.error(message);
    }
}

// 4. 具体创建者
public class FileLoggerFactory extends LoggerFactory {
    @Override
    public Logger createLogger() {
        // 可以在这里进行复杂的初始化操作
        System.out.println("创建文件日志记录器...");
        return new FileLogger();
    }
}

public class DatabaseLoggerFactory extends LoggerFactory {
    @Override
    public Logger createLogger() {
        System.out.println("创建数据库日志记录器...");
        return new DatabaseLogger();
    }
}

public class ConsoleLoggerFactory extends LoggerFactory {
    @Override
    public Logger createLogger() {
        System.out.println("创建控制台日志记录器...");
        return new ConsoleLogger();
    }
}

// 5. 客户端使用
public class LoggerClient {
    public static void main(String[] args) {
        // 使用文件日志
        LoggerFactory fileFactory = new FileLoggerFactory();
        fileFactory.log("这是一个信息日志");
        fileFactory.error("这是一个错误日志");
        
        // 使用数据库日志
        LoggerFactory dbFactory = new DatabaseLoggerFactory();
        dbFactory.log("数据库操作日志");
        
        // 使用控制台日志
        LoggerFactory consoleFactory = new ConsoleLoggerFactory();
        consoleFactory.warn("这是一个警告");
    }
}

4. 带参数的工厂方法

// 增强的工厂方法
public abstract class EnhancedLoggerFactory {
    /**
     * 带参数的工厂方法
     */
    public abstract Logger createLogger(LoggerConfig config);
    
    /**
     * 重载的工厂方法
     */
    public Logger createLogger() {
        return createLogger(LoggerConfig.defaultConfig());
    }
}

// 配置类
public class LoggerConfig {
    private String level;
    private String format;
    private String filePath;
    
    public LoggerConfig(String level, String format, String filePath) {
        this.level = level;
        this.format = format;
        this.filePath = filePath;
    }
    
    public static LoggerConfig defaultConfig() {
        return new LoggerConfig("INFO", "TEXT", "logs/app.log");
    }
    
    // getters and setters
}

// 具体实现
public class ConfigurableFileLoggerFactory extends EnhancedLoggerFactory {
    @Override
    public Logger createLogger(LoggerConfig config) {
        FileLogger logger = new FileLogger();
        // 根据配置初始化logger
        System.out.println("使用配置创建文件日志: " + config.getFilePath());
        return logger;
    }
}

5. 工厂方法模式的优缺点

​优点:​

  • 完全符合开闭原则

  • 客户端与具体产品解耦

  • 易于扩展新的产品族

​缺点:​

  • 类的数量增加

  • 增加了系统的复杂性


四、抽象工厂模式(Abstract Factory Pattern)

1. 核心思想

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

2. 适用场景

  • 系统需要一系列相互关联的产品

  • 系统需要动态切换产品族

  • 产品等级结构稳定,但产品族经常变化

3. 代码实现:跨平台UI组件

// 1. 抽象产品族 - UI组件
public interface Button {
    void render();
    void onClick();
}

public interface TextField {
    void render();
    String getText();
    void setText(String text);
}

public interface Checkbox {
    void render();
    boolean isChecked();
    void setChecked(boolean checked);
}

// 2. 具体产品 - Windows风格
public class WindowsButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染Windows风格按钮");
    }
    
    @Override
    public void onClick() {
        System.out.println("Windows按钮被点击");
    }
}

public class WindowsTextField implements TextField {
    private String text = "";
    
    @Override
    public void render() {
        System.out.println("渲染Windows风格文本框");
    }
    
    @Override
    public String getText() {
        return text;
    }
    
    @Override
    public void setText(String text) {
        this.text = text;
    }
}

public class WindowsCheckbox implements Checkbox {
    private boolean checked = false;
    
    @Override
    public void render() {
        System.out.println("渲染Windows风格复选框: " + (checked ? "✓" : "□"));
    }
    
    @Override
    public boolean isChecked() {
        return checked;
    }
    
    @Override
    public void setChecked(boolean checked) {
        this.checked = checked;
    }
}

// 3. 具体产品 - Mac风格
public class MacButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染Mac风格按钮");
    }
    
    @Override
    public void onClick() {
        System.out.println("Mac按钮被点击");
    }
}

public class MacTextField implements TextField {
    private String text = "";
    
    @Override
    public void render() {
        System.out.println("渲染Mac风格文本框");
    }
    
    @Override
    public String getText() {
        return text;
    }
    
    @Override
    public void setText(String text) {
        this.text = text;
    }
}

public class MacCheckbox implements Checkbox {
    private boolean checked = false;
    
    @Override
    public void render() {
        System.out.println("渲染Mac风格复选框: " + (checked ? "✓" : "□"));
    }
    
    @Override
    public boolean isChecked() {
        return checked;
    }
    
    @Override
    public void setChecked(boolean checked) {
        this.checked = checked;
    }
}

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

// 5. 具体工厂
public class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }
    
    @Override
    public TextField createTextField() {
        return new WindowsTextField();
    }
    
    @Override
    public Checkbox createCheckbox() {
        return new WindowsCheckbox();
    }
}

public class MacFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }
    
    @Override
    public TextField createTextField() {
        return new MacTextField();
    }
    
    @Override
    public Checkbox createCheckbox() {
        return new MacCheckbox();
    }
}

// 6. 客户端代码
public class Application {
    private Button button;
    private TextField textField;
    private Checkbox checkbox;
    private GUIFactory factory;
    
    public Application(GUIFactory factory) {
        this.factory = factory;
        createUI();
    }
    
    private void createUI() {
        this.button = factory.createButton();
        this.textField = factory.createTextField();
        this.checkbox = factory.createCheckbox();
    }
    
    public void render() {
        System.out.println("=== 渲染UI界面 ===");
        button.render();
        textField.render();
        checkbox.render();
    }
    
    public void simulateUserAction() {
        System.out.println("\n=== 模拟用户操作 ===");
        button.onClick();
        textField.setText("Hello World");
        checkbox.setChecked(true);
        checkbox.render();
    }
}

// 7. 配置类 - 根据环境选择工厂
public class FactoryConfig {
    public static GUIFactory createFactory() {
        String os = System.getProperty("os.name").toLowerCase();
        
        if (os.contains("win")) {
            return new WindowsFactory();
        } else if (os.contains("mac")) {
            return new MacFactory();
        } else {
            throw new UnsupportedOperationException("不支持的操作系统: " + os);
        }
    }
}

// 8. 客户端使用
public class AbstractFactoryClient {
    public static void main(String[] args) {
        // 根据当前操作系统自动选择工厂
        GUIFactory factory = FactoryConfig.createFactory();
        
        Application app = new Application(factory);
        app.render();
        app.simulateUserAction();
        
        // 手动指定工厂
        System.out.println("\n=== 测试Mac风格 ===");
        Application macApp = new Application(new MacFactory());
        macApp.render();
    }
}

4. 抽象工厂扩展:新增产品族

// 新增Linux风格产品族
public class LinuxButton implements Button {
    @Override
    public void render() {
        System.out.println("渲染Linux风格按钮");
    }
    
    @Override
    public void onClick() {
        System.out.println("Linux按钮被点击");
    }
}

public class LinuxTextField implements TextField {
    private String text = "";
    
    @Override
    public void render() {
        System.out.println("渲染Linux风格文本框");
    }
    
    @Override
    public String getText() {
        return text;
    }
    
    @Override
    public void setText(String text) {
        this.text = text;
    }
}

public class LinuxCheckbox implements Checkbox {
    private boolean checked = false;
    
    @Override
    public void render() {
        System.out.println("渲染Linux风格复选框: " + (checked ? "✓" : "□"));
    }
    
    @Override
    public boolean isChecked() {
        return checked;
    }
    
    @Override
    public void setChecked(boolean checked) {
        this.checked = checked;
    }
}

public class LinuxFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new LinuxButton();
    }
    
    @Override
    public TextField createTextField() {
        return new LinuxTextField();
    }
    
    @Override
    public Checkbox createCheckbox() {
        return new LinuxCheckbox();
    }
}

// 更新配置类
public class EnhancedFactoryConfig {
    public static GUIFactory createFactory(String style) {
        if (style == null) {
            // 默认根据操作系统
            String os = System.getProperty("os.name").toLowerCase();
            style = os.contains("win") ? "windows" : 
                   os.contains("mac") ? "mac" : "linux";
        }
        
        switch (style.toLowerCase()) {
            case "windows":
                return new WindowsFactory();
            case "mac":
                return new MacFactory();
            case "linux":
                return new LinuxFactory();
            default:
                throw new IllegalArgumentException("不支持的样式: " + style);
        }
    }
}

五、工厂模式在JDK和框架中的应用

1. JDK中的工厂模式

// Calendar类的工厂方法
public class JDKFactoryExample {
    public static void main(String[] args) {
        // 工厂方法模式
        Calendar calendar = Calendar.getInstance();  // 根据时区返回具体实例
        Calendar chinaCalendar = Calendar.getInstance(TimeZone.getTimeZone("Asia/Shanghai"));
        
        // 简单工厂模式
        NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.CHINA);
        NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.US);
    }
}

2. Spring框架中的工厂模式

// BeanFactory - 工厂方法模式的典型应用
public class SpringFactoryExample {
    @Configuration
    public static class AppConfig {
        // 工厂方法创建Bean
        @Bean
        public DataSource dataSource() {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
            dataSource.setUsername("root");
            dataSource.setPassword("password");
            return dataSource;
        }
        
        // 使用FactoryBean接口
        @Bean
        public SqlSessionFactory sqlSessionFactory() throws Exception {
            SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
            factoryBean.setDataSource(dataSource());
            return factoryBean.getObject();  // 工厂方法
        }
    }
}

3. 日志框架中的工厂模式

public class LoggingFactoryExample {
    public static void main(String[] args) {
        // Log4j2的工厂方法
        Logger logger = LogManager.getLogger(LoggingFactoryExample.class);
        
        // SLF4J的工厂方法
        org.slf4j.Logger slf4jLogger = org.slf4j.LoggerFactory.getLogger(LoggingFactoryExample.class);
    }
}

六、工厂模式的最佳实践

1. 选择合适的工厂模式

场景

推荐模式

理由

产品类型固定,不会频繁扩展

简单工厂模式

实现简单

需要支持产品家族扩展

工厂方法模式

符合开闭原则

需要创建相关产品族

抽象工厂模式

保证产品兼容性

对象创建过程复杂

任何工厂模式

封装复杂创建逻辑

2. 使用依赖注入

// 结合Spring的依赖注入
@Service
public class OrderService {
    private final PaymentFactory paymentFactory;
    
    // 通过构造器注入工厂
    public OrderService(PaymentFactory paymentFactory) {
        this.paymentFactory = paymentFactory;
    }
    
    public void processOrder(Order order, String paymentType) {
        Payment payment = paymentFactory.createPayment(paymentType);
        payment.pay(order.getAmount());
    }
}

// 配置类
@Configuration
public class FactoryConfig {
    @Bean
    public PaymentFactory paymentFactory() {
        return new PaymentFactory();
    }
}

3. 使用枚举优化工厂

public enum CarFactory {
    BENZ {
        @Override
        public Car createCar() {
            return new BenzCar();
        }
    },
    BMW {
        @Override
        public Car createCar() {
            return new BMWCar();
        }
    },
    AUDI {
        @Override
        public Car createCar() {
            return new AudiCar();
        }
    };
    
    public abstract Car createCar();
    
    // 静态工厂方法
    public static Car createCar(String type) {
        return valueOf(type.toUpperCase()).createCar();
    }
}

// 使用示例
Car benz = CarFactory.BENZ.createCar();
Car bmw = CarFactory.createCar("bmw");

七、总结

三种工厂模式对比

特性

简单工厂模式

工厂方法模式

抽象工厂模式

创建对象方式

静态方法

工厂方法

工厂接口

扩展性

违反开闭原则

符合开闭原则

符合开闭原则

复杂度

简单

中等

复杂

适用场景

产品类型固定

产品等级结构稳定

产品族经常变化

核心价值

  1. ​解耦​​:将对象创建与使用分离

  2. ​可维护性​​:集中管理创建逻辑

  3. ​可扩展性​​:易于添加新产品

  4. ​可测试性​​:便于单元测试和Mock

工厂模式是面向对象设计中最重要的模式之一,深入理解并合理运用工厂模式,可以显著提高代码的质量和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值