工厂方法模式全方位深度解析

3 阅读19分钟

一、模式定义

工厂方法模式是一种创建型设计模式,它定义了一个创建对象的接口,但由子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类

二、Java源代码实现

1. 经典工厂方法模式实现

// 1. 抽象产品接口
public interface Product {
    void operation();
    String getName();
}

// 2. 具体产品实现
// 具体产品A
public class ConcreteProductA implements Product {
    @Override
    public void operation() {
        System.out.println("执行产品A的操作");
    }
    
    @Override
    public String getName() {
        return "ProductA";
    }
}

// 具体产品B
public class ConcreteProductB implements Product {
    @Override
    public void operation() {
        System.out.println("执行产品B的操作");
    }
    
    @Override
    public String getName() {
        return "ProductB";
    }
}

// 具体产品C
public class ConcreteProductC implements Product {
    @Override
    public void operation() {
        System.out.println("执行产品C的操作");
    }
    
    @Override
    public String getName() {
        return "ProductC";
    }
}

// 3. 抽象创建者(Creator)
public abstract class Creator {
    // 工厂方法 - 抽象方法,由子类实现
    public abstract Product createProduct();
    
    // 也可以定义默认的工厂方法
    public Product createDefaultProduct() {
        return new ConcreteProductA(); // 默认返回产品A
    }
    
    // 模板方法 - 使用工厂方法创建产品
    public void operation() {
        Product product = createProduct();
        System.out.println("创建产品: " + product.getName());
        product.operation();
    }
    
    // 钩子方法
    protected boolean shouldLog() {
        return true;
    }
    
    // 带钩子的模板方法
    public void operationWithHook() {
        Product product = createProduct();
        if (shouldLog()) {
            System.out.println("【日志】开始创建产品: " + product.getName());
        }
        product.operation();
        if (shouldLog()) {
            System.out.println("【日志】产品创建完成: " + product.getName());
        }
    }
}

// 4. 具体创建者实现
// 具体创建者A - 创建产品A
public class ConcreteCreatorA extends Creator {
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
    
    // 可选的:重写钩子方法
    @Override
    protected boolean shouldLog() {
        return false; // 不记录日志
    }
}

// 具体创建者B - 创建产品B
public class ConcreteCreatorB extends Creator {
    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

// 具体创建者C - 创建产品C
public class ConcreteCreatorC extends Creator {
    @Override
    public Product createProduct() {
        return new ConcreteProductC();
    }
    
    // 可选的:扩展功能
    public Product createProductWithConfig(String config) {
        ConcreteProductC product = new ConcreteProductC();
        // 应用配置...
        return product;
    }
}

// 5. 参数化工厂方法
public class ParameterizedCreator extends Creator {
    private String productType;
    
    public ParameterizedCreator(String productType) {
        this.productType = productType;
    }
    
    @Override
    public Product createProduct() {
        switch (productType.toLowerCase()) {
            case "a":
                return new ConcreteProductA();
            case "b":
                return new ConcreteProductB();
            case "c":
                return new ConcreteProductC();
            default:
                throw new IllegalArgumentException("未知的产品类型: " + productType);
        }
    }
    
    // 设置产品类型
    public void setProductType(String productType) {
        this.productType = productType;
    }
}

// 6. 客户端使用示例
public class FactoryMethodClient {
    public static void main(String[] args) {
        System.out.println("=== 工厂方法模式示例 ===\n");
        
        // 示例1:基本使用
        testBasicFactoryMethod();
        
        // 示例2:参数化工厂
        testParameterizedFactory();
        
        // 示例3:模板方法结合
        testTemplateMethod();
        
        // 示例4:复杂场景
        testComplexScenario();
    }
    
    private static void testBasicFactoryMethod() {
        System.out.println("1. 基本工厂方法使用:");
        
        Creator creatorA = new ConcreteCreatorA();
        Product productA = creatorA.createProduct();
        productA.operation();
        System.out.println("产品名称: " + productA.getName());
        
        Creator creatorB = new ConcreteCreatorB();
        Product productB = creatorB.createProduct();
        productB.operation();
        System.out.println("产品名称: " + productB.getName());
        
        // 使用模板方法
        System.out.println("\n使用模板方法:");
        creatorA.operation();
        creatorB.operation();
    }
    
    private static void testParameterizedFactory() {
        System.out.println("\n2. 参数化工厂方法:");
        
        ParameterizedCreator creator = new ParameterizedCreator("a");
        Product productA = creator.createProduct();
        productA.operation();
        
        creator.setProductType("b");
        Product productB = creator.createProduct();
        productB.operation();
        
        creator.setProductType("c");
        Product productC = creator.createProduct();
        productC.operation();
        
        // 测试错误类型
        try {
            creator.setProductType("d");
            creator.createProduct();
        } catch (IllegalArgumentException e) {
            System.out.println("预期错误: " + e.getMessage());
        }
    }
    
    private static void testTemplateMethod() {
        System.out.println("\n3. 模板方法与工厂方法结合:");
        
        Creator creatorA = new ConcreteCreatorA();
        Creator creatorB = new ConcreteCreatorB();
        Creator creatorC = new ConcreteCreatorC();
        
        System.out.println("创建者A操作(不记录日志):");
        creatorA.operationWithHook();
        
        System.out.println("\n创建者B操作(记录日志):");
        creatorB.operationWithHook();
        
        System.out.println("\n创建者C操作(记录日志):");
        creatorC.operationWithHook();
    }
    
    private static void testComplexScenario() {
        System.out.println("\n4. 复杂场景示例:");
        
        // 创建一系列产品
        List<Creator> creators = Arrays.asList(
            new ConcreteCreatorA(),
            new ConcreteCreatorB(),
            new ConcreteCreatorC(),
            new ParameterizedCreator("a")
        );
        
        for (Creator creator : creators) {
            Product product = creator.createProduct();
            System.out.println("创建的产品: " + product.getClass().getSimpleName());
            product.operation();
        }
    }
}

2. 日志系统示例

// 1. 日志产品接口
public interface Logger {
    void log(String message);
    void error(String message);
    void warn(String message);
    void debug(String message);
    
    // 默认方法
    default void log(String level, String message) {
        System.out.println("[" + level + "] " + message);
    }
}

// 2. 具体日志实现
// 控制台日志
public class ConsoleLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("[INFO] " + message);
    }
    
    @Override
    public void error(String message) {
        System.err.println("[ERROR] " + message);
    }
    
    @Override
    public void warn(String message) {
        System.out.println("[WARN] " + message);
    }
    
    @Override
    public void debug(String message) {
        System.out.println("[DEBUG] " + message);
    }
}

// 文件日志
public class FileLogger implements Logger {
    private String filePath;
    
    public FileLogger(String filePath) {
        this.filePath = filePath;
    }
    
    @Override
    public void log(String message) {
        writeToFile("[INFO] " + message);
    }
    
    @Override
    public void error(String message) {
        writeToFile("[ERROR] " + message);
    }
    
    @Override
    public void warn(String message) {
        writeToFile("[WARN] " + message);
    }
    
    @Override
    public void debug(String message) {
        writeToFile("[DEBUG] " + message);
    }
    
    private void writeToFile(String content) {
        try (PrintWriter writer = new PrintWriter(new FileWriter(filePath, true))) {
            writer.println(content);
        } catch (IOException e) {
            System.err.println("写入文件失败: " + e.getMessage());
        }
    }
}

// 数据库日志
public class DatabaseLogger implements Logger {
    private String connectionString;
    
    public DatabaseLogger(String connectionString) {
        this.connectionString = connectionString;
    }
    
    @Override
    public void log(String message) {
        saveToDatabase("INFO", message);
    }
    
    @Override
    public void error(String message) {
        saveToDatabase("ERROR", message);
    }
    
    @Override
    public void warn(String message) {
        saveToDatabase("WARN", message);
    }
    
    @Override
    public void debug(String message) {
        saveToDatabase("DEBUG", message);
    }
    
    private void saveToDatabase(String level, String message) {
        // 模拟保存到数据库
        System.out.println("保存到数据库 [" + connectionString + "]: [" + level + "] " + message);
    }
}

// 网络日志
public class NetworkLogger implements Logger {
    private String serverUrl;
    
    public NetworkLogger(String serverUrl) {
        this.serverUrl = serverUrl;
    }
    
    @Override
    public void log(String message) {
        sendToServer("INFO", message);
    }
    
    @Override
    public void error(String message) {
        sendToServer("ERROR", message);
    }
    
    @Override
    public void warn(String message) {
        sendToServer("WARN", message);
    }
    
    @Override
    public void debug(String message) {
        sendToServer("DEBUG", message);
    }
    
    private void sendToServer(String level, String message) {
        // 模拟发送到网络服务器
        System.out.println("发送到服务器 [" + serverUrl + "]: [" + level + "] " + message);
    }
}

// 3. 抽象日志工厂
public abstract class LoggerFactory {
    // 工厂方法
    public abstract Logger createLogger();
    
    // 带参数的工厂方法
    public abstract Logger createLogger(String config);
    
    // 模板方法
    public void logMessage(String message) {
        Logger logger = createLogger();
        logger.log(message);
    }
    
    // 默认实现
    protected Logger createDefaultLogger() {
        return new ConsoleLogger();
    }
}

// 4. 具体日志工厂
// 控制台日志工厂
public class ConsoleLoggerFactory extends LoggerFactory {
    @Override
    public Logger createLogger() {
        return new ConsoleLogger();
    }
    
    @Override
    public Logger createLogger(String config) {
        // 控制台日志不需要配置
        return new ConsoleLogger();
    }
}

// 文件日志工厂
public class FileLoggerFactory extends LoggerFactory {
    private String defaultFilePath = "app.log";
    
    @Override
    public Logger createLogger() {
        return new FileLogger(defaultFilePath);
    }
    
    @Override
    public Logger createLogger(String config) {
        if (config != null && !config.trim().isEmpty()) {
            return new FileLogger(config);
        }
        return new FileLogger(defaultFilePath);
    }
    
    public void setDefaultFilePath(String filePath) {
        this.defaultFilePath = filePath;
    }
}

// 数据库日志工厂
public class DatabaseLoggerFactory extends LoggerFactory {
    private String defaultConnectionString = "jdbc:mysql://localhost:3306/logs";
    
    @Override
    public Logger createLogger() {
        return new DatabaseLogger(defaultConnectionString);
    }
    
    @Override
    public Logger createLogger(String config) {
        if (config != null && !config.trim().isEmpty()) {
            return new DatabaseLogger(config);
        }
        return new DatabaseLogger(defaultConnectionString);
    }
}

// 网络日志工厂
public class NetworkLoggerFactory extends LoggerFactory {
    private String defaultServerUrl = "http://logserver:8080/log";
    
    @Override
    public Logger createLogger() {
        return new NetworkLogger(defaultServerUrl);
    }
    
    @Override
    public Logger createLogger(String config) {
        if (config != null && !config.trim().isEmpty()) {
            return new NetworkLogger(config);
        }
        return new NetworkLogger(defaultServerUrl);
    }
}

// 5. 日志工厂提供者
public class LoggerFactoryProvider {
    public enum LoggerType {
        CONSOLE,
        FILE,
        DATABASE,
        NETWORK
    }
    
    public static LoggerFactory getFactory(LoggerType type) {
        switch (type) {
            case CONSOLE:
                return new ConsoleLoggerFactory();
            case FILE:
                return new FileLoggerFactory();
            case DATABASE:
                return new DatabaseLoggerFactory();
            case NETWORK:
                return new NetworkLoggerFactory();
            default:
                return new ConsoleLoggerFactory(); // 默认控制台
        }
    }
    
    // 从配置文件获取工厂
    public static LoggerFactory getFactoryFromConfig() {
        Properties props = new Properties();
        try (InputStream input = LoggerFactoryProvider.class
                .getResourceAsStream("/logger.properties")) {
            if (input != null) {
                props.load(input);
                String type = props.getProperty("logger.type", "CONSOLE");
                String config = props.getProperty("logger.config");
                
                LoggerFactory factory = getFactory(LoggerType.valueOf(type.toUpperCase()));
                if (factory instanceof FileLoggerFactory && config != null) {
                    ((FileLoggerFactory) factory).setDefaultFilePath(config);
                }
                return factory;
            }
        } catch (IOException e) {
            // 使用默认配置
        }
        return new ConsoleLoggerFactory();
    }
}

// 6. 日志管理器
public class LogManager {
    private LoggerFactory factory;
    private Logger logger;
    
    public LogManager(LoggerFactory factory) {
        this.factory = factory;
        this.logger = factory.createLogger();
    }
    
    public void info(String message) {
        logger.log(message);
    }
    
    public void error(String message) {
        logger.error(message);
    }
    
    public void warn(String message) {
        logger.warn(message);
    }
    
    public void debug(String message) {
        logger.debug(message);
    }
    
    public void reloadLogger(String config) {
        this.logger = factory.createLogger(config);
    }
}

// 7. 客户端使用
public class LoggerClient {
    public static void main(String[] args) {
        System.out.println("=== 日志系统工厂方法示例 ===\n");
        
        // 示例1:使用不同工厂
        testDifferentFactories();
        
        // 示例2:通过提供者获取工厂
        testFactoryProvider();
        
        // 示例3:完整的日志管理器
        testLogManager();
        
        // 示例4:配置文件驱动
        testConfigDriven();
    }
    
    private static void testDifferentFactories() {
        System.out.println("1. 使用不同日志工厂:");
        
        // 控制台日志
        LoggerFactory consoleFactory = new ConsoleLoggerFactory();
        Logger consoleLogger = consoleFactory.createLogger();
        consoleLogger.log("这是一条控制台日志");
        
        // 文件日志
        LoggerFactory fileFactory = new FileLoggerFactory();
        Logger fileLogger = fileFactory.createLogger("application.log");
        fileLogger.log("这是一条文件日志");
        
        // 数据库日志
        LoggerFactory dbFactory = new DatabaseLoggerFactory();
        Logger dbLogger = dbFactory.createLogger();
        dbLogger.log("这是一条数据库日志");
        
        // 网络日志
        LoggerFactory networkFactory = new NetworkLoggerFactory();
        Logger networkLogger = networkFactory.createLogger("http://example.com/log");
        networkLogger.log("这是一条网络日志");
    }
    
    private static void testFactoryProvider() {
        System.out.println("\n2. 通过提供者获取工厂:");
        
        LoggerFactory factory = LoggerFactoryProvider.getFactory(LoggerFactoryProvider.LoggerType.FILE);
        factory.logMessage("通过提供者创建的日志");
        
        factory = LoggerFactoryProvider.getFactory(LoggerFactoryProvider.LoggerType.DATABASE);
        factory.logMessage("数据库日志消息");
    }
    
    private static void testLogManager() {
        System.out.println("\n3. 使用日志管理器:");
        
        LogManager consoleManager = new LogManager(new ConsoleLoggerFactory());
        consoleManager.info("信息日志");
        consoleManager.error("错误日志");
        consoleManager.warn("警告日志");
        consoleManager.debug("调试日志");
        
        LogManager fileManager = new LogManager(new FileLoggerFactory());
        fileManager.info("文件信息日志");
    }
    
    private static void testConfigDriven() {
        System.out.println("\n4. 配置文件驱动:");
        
        LoggerFactory factory = LoggerFactoryProvider.getFactoryFromConfig();
        Logger logger = factory.createLogger();
        logger.log("从配置文件创建的日志");
    }
}

3. 连接池工厂示例

// 1. 数据库连接接口
public interface Connection {
    void connect();
    void disconnect();
    void execute(String sql);
    boolean isConnected();
    
    // 默认方法
    default void executeBatch(List<String> sqls) {
        for (String sql : sqls) {
            execute(sql);
        }
    }
}

// 2. 具体连接实现
// MySQL连接
public class MySQLConnection implements Connection {
    private String url;
    private String username;
    private String password;
    private boolean connected = false;
    
    public MySQLConnection(String url, String username, String password) {
        this.url = url;
        this.username = username;
        this.password = password;
    }
    
    @Override
    public void connect() {
        System.out.println("连接到MySQL: " + url);
        // 模拟连接过程
        try {
            Thread.sleep(100); // 模拟连接耗时
            connected = true;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    @Override
    public void disconnect() {
        if (connected) {
            System.out.println("断开MySQL连接");
            connected = false;
        }
    }
    
    @Override
    public void execute(String sql) {
        if (!connected) {
            throw new IllegalStateException("连接未建立");
        }
        System.out.println("MySQL执行: " + sql);
    }
    
    @Override
    public boolean isConnected() {
        return connected;
    }
}

// PostgreSQL连接
public class PostgreSQLConnection implements Connection {
    private String url;
    private String username;
    private String password;
    private boolean connected = false;
    
    public PostgreSQLConnection(String url, String username, String password) {
        this.url = url;
        this.username = username;
        this.password = password;
    }
    
    @Override
    public void connect() {
        System.out.println("连接到PostgreSQL: " + url);
        try {
            Thread.sleep(150); // PostgreSQL连接稍慢
            connected = true;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    @Override
    public void disconnect() {
        if (connected) {
            System.out.println("断开PostgreSQL连接");
            connected = false;
        }
    }
    
    @Override
    public void execute(String sql) {
        if (!connected) {
            throw new IllegalStateException("连接未建立");
        }
        System.out.println("PostgreSQL执行: " + sql);
    }
    
    @Override
    public boolean isConnected() {
        return connected;
    }
}

// Oracle连接
public class OracleConnection implements Connection {
    private String url;
    private String username;
    private String password;
    private boolean connected = false;
    
    public OracleConnection(String url, String username, String password) {
        this.url = url;
        this.username = username;
        this.password = password;
    }
    
    @Override
    public void connect() {
        System.out.println("连接到Oracle: " + url);
        try {
            Thread.sleep(200); // Oracle连接最慢
            connected = true;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    @Override
    public void disconnect() {
        if (connected) {
            System.out.println("断开Oracle连接");
            connected = false;
        }
    }
    
    @Override
    public void execute(String sql) {
        if (!connected) {
            throw new IllegalStateException("连接未建立");
        }
        System.out.println("Oracle执行: " + sql);
    }
    
    @Override
    public boolean isConnected() {
        return connected;
    }
}

// 3. 抽象连接工厂
public abstract class ConnectionFactory {
    // 工厂方法
    public abstract Connection createConnection();
    
    // 带参数的工厂方法
    public abstract Connection createConnection(String url, String username, String password);
    
    // 模板方法:创建并连接
    public Connection createAndConnect() {
        Connection connection = createConnection();
        connection.connect();
        return connection;
    }
    
    public Connection createAndConnect(String url, String username, String password) {
        Connection connection = createConnection(url, username, password);
        connection.connect();
        return connection;
    }
    
    // 连接池支持
    public List<Connection> createConnectionPool(int size) {
        List<Connection> pool = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            pool.add(createConnection());
        }
        return pool;
    }
}

// 4. 具体连接工厂
// MySQL连接工厂
public class MySQLConnectionFactory extends ConnectionFactory {
    private String defaultUrl = "jdbc:mysql://localhost:3306/default";
    private String defaultUsername = "root";
    private String defaultPassword = "password";
    
    @Override
    public Connection createConnection() {
        return new MySQLConnection(defaultUrl, defaultUsername, defaultPassword);
    }
    
    @Override
    public Connection createConnection(String url, String username, String password) {
        return new MySQLConnection(url, username, password);
    }
    
    // 配置方法
    public void configure(String url, String username, String password) {
        this.defaultUrl = url;
        this.defaultUsername = username;
        this.defaultPassword = password;
    }
}

// PostgreSQL连接工厂
public class PostgreSQLConnectionFactory extends ConnectionFactory {
    private String defaultUrl = "jdbc:postgresql://localhost:5432/default";
    private String defaultUsername = "postgres";
    private String defaultPassword = "password";
    
    @Override
    public Connection createConnection() {
        return new PostgreSQLConnection(defaultUrl, defaultUsername, defaultPassword);
    }
    
    @Override
    public Connection createConnection(String url, String username, String password) {
        return new PostgreSQLConnection(url, username, password);
    }
}

// Oracle连接工厂
public class OracleConnectionFactory extends ConnectionFactory {
    private String defaultUrl = "jdbc:oracle:thin:@localhost:1521:orcl";
    private String defaultUsername = "system";
    private String defaultPassword = "password";
    
    @Override
    public Connection createConnection() {
        return new OracleConnection(defaultUrl, defaultUsername, defaultPassword);
    }
    
    @Override
    public Connection createConnection(String url, String username, String password) {
        return new OracleConnection(url, username, password);
    }
}

// 5. 连接池管理器
public class ConnectionPoolManager {
    private ConnectionFactory factory;
    private List<Connection> connectionPool = new ArrayList<>();
    private Queue<Connection> availableConnections = new ConcurrentLinkedQueue<>();
    private int maxPoolSize = 10;
    private int initialPoolSize = 5;
    
    public ConnectionPoolManager(ConnectionFactory factory) {
        this.factory = factory;
        initializePool();
    }
    
    private void initializePool() {
        for (int i = 0; i < initialPoolSize; i++) {
            Connection connection = factory.createConnection();
            connection.connect();
            connectionPool.add(connection);
            availableConnections.add(connection);
        }
    }
    
    public synchronized Connection getConnection() {
        if (!availableConnections.isEmpty()) {
            return availableConnections.poll();
        }
        
        if (connectionPool.size() < maxPoolSize) {
            Connection connection = factory.createConnection();
            connection.connect();
            connectionPool.add(connection);
            return connection;
        }
        
        // 等待连接可用
        try {
            wait(1000);
            if (!availableConnections.isEmpty()) {
                return availableConnections.poll();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        throw new RuntimeException("连接池已满,无法获取连接");
    }
    
    public void releaseConnection(Connection connection) {
        if (connection != null && connection.isConnected()) {
            availableConnections.add(connection);
            notifyAll();
        }
    }
    
    public void closeAll() {
        for (Connection connection : connectionPool) {
            connection.disconnect();
        }
        connectionPool.clear();
        availableConnections.clear();
    }
}

// 6. 客户端使用
public class ConnectionFactoryClient {
    public static void main(String[] args) {
        System.out.println("=== 数据库连接工厂示例 ===\n");
        
        // 示例1:基本使用
        testBasicConnectionFactories();
        
        // 示例2:连接池管理
        testConnectionPool();
        
        // 示例3:性能测试
        testPerformance();
    }
    
    private static void testBasicConnectionFactories() {
        System.out.println("1. 基本连接工厂使用:");
        
        ConnectionFactory mysqlFactory = new MySQLConnectionFactory();
        ConnectionFactory pgFactory = new PostgreSQLConnectionFactory();
        ConnectionFactory oracleFactory = new OracleConnectionFactory();
        
        // 创建MySQL连接
        Connection mysqlConn = mysqlFactory.createAndConnect();
        mysqlConn.execute("SELECT * FROM users");
        mysqlConn.disconnect();
        
        // 创建PostgreSQL连接
        Connection pgConn = pgFactory.createAndConnect(
            "jdbc:postgresql://localhost:5432/mydb",
            "admin",
            "admin123"
        );
        pgConn.execute("SELECT * FROM products");
        pgConn.disconnect();
        
        // 创建Oracle连接
        Connection oracleConn = oracleFactory.createAndConnect();
        oracleConn.execute("SELECT * FROM employees");
        oracleConn.disconnect();
    }
    
    private static void testConnectionPool() {
        System.out.println("\n2. 连接池管理:");
        
        ConnectionFactory factory = new MySQLConnectionFactory();
        ConnectionPoolManager poolManager = new ConnectionPoolManager(factory);
        
        // 获取多个连接
        List<Connection> connections = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
            Connection conn = poolManager.getConnection();
            connections.add(conn);
            System.out.println("获取连接 " + (i + 1) + ": " + conn.getClass().getSimpleName());
        }
        
        // 使用连接
        for (Connection conn : connections) {
            conn.execute("SELECT 1");
        }
        
        // 释放连接
        for (Connection conn : connections) {
            poolManager.releaseConnection(conn);
        }
        
        // 关闭所有连接
        poolManager.closeAll();
    }
    
    private static void testPerformance() {
        System.out.println("\n3. 性能测试:");
        
        ConnectionFactory factory = new MySQLConnectionFactory();
        
        long startTime = System.currentTimeMillis();
        
        // 测试创建100个连接的耗时
        for (int i = 0; i < 100; i++) {
            Connection conn = factory.createConnection();
            conn.connect();
            conn.execute("TEST QUERY");
            conn.disconnect();
        }
        
        long duration = System.currentTimeMillis() - startTime;
        System.out.println("创建100个连接耗时: " + duration + "ms");
        
        // 使用连接池的性能对比
        startTime = System.currentTimeMillis();
        ConnectionPoolManager poolManager = new ConnectionPoolManager(factory);
        
        for (int i = 0; i < 100; i++) {
            Connection conn = poolManager.getConnection();
            conn.execute("TEST QUERY");
            poolManager.releaseConnection(conn);
        }
        
        poolManager.closeAll();
        duration = System.currentTimeMillis() - startTime;
        System.out.println("使用连接池执行100次查询耗时: " + duration + "ms");
    }
}

三、应用场景深度解析

1. 框架开发场景

// Spring框架中的工厂方法
public interface ApplicationContext {
    <T> T getBean(Class<T> requiredType);
    <T> T getBean(String name, Class<T> requiredType);
    Object getBean(String name);
}

// 具体实现
public class ClassPathXmlApplicationContext implements ApplicationContext {
    @Override
    public <T> T getBean(Class<T> requiredType) {
        // 通过工厂方法创建Bean
        return createBean(requiredType);
    }
    
    private <T> T createBean(Class<T> beanClass) {
        // 具体的创建逻辑
        try {
            return beanClass.newInstance();
        } catch (Exception e) {
            throw new RuntimeException("创建Bean失败", e);
        }
    }
}

// MyBatis中的SqlSessionFactory
public interface SqlSessionFactory {
    SqlSession openSession();
    SqlSession openSession(boolean autoCommit);
    SqlSession openSession(Connection connection);
    Configuration getConfiguration();
}

2. 插件系统

// 插件工厂
public interface PluginFactory {
    Plugin createPlugin(String pluginId);
    Plugin createPlugin(PluginDescriptor descriptor);
    
    // 默认实现
    default Plugin createDefaultPlugin() {
        return new DefaultPlugin();
    }
}

// 具体插件工厂
public class TextPluginFactory implements PluginFactory {
    @Override
    public Plugin createPlugin(String pluginId) {
        switch (pluginId) {
            case "markdown":
                return new MarkdownPlugin();
            case "html":
                return new HtmlPlugin();
            case "plain":
                return new PlainTextPlugin();
            default:
                throw new IllegalArgumentException("未知的插件: " + pluginId);
        }
    }
    
    @Override
    public Plugin createPlugin(PluginDescriptor descriptor) {
        // 根据描述符创建插件
        Plugin plugin = createPlugin(descriptor.getType());
        plugin.initialize(descriptor.getConfig());
        return plugin;
    }
}

3. 游戏开发

// 游戏对象工厂
public abstract class GameObjectFactory {
    public abstract GameObject createEnemy();
    public abstract GameObject createPlayer();
    public abstract GameObject createItem();
    
    // 模板方法
    public GameObject createGameObject(String type) {
        switch (type.toLowerCase()) {
            case "enemy":
                return createEnemy();
            case "player":
                return createPlayer();
            case "item":
                return createItem();
            default:
                throw new IllegalArgumentException("未知的游戏对象类型: " + type);
        }
    }
    
    // 工厂方法
    protected abstract GameObject instantiateGameObject(String type);
}

// 具体游戏主题工厂
public class MedievalGameFactory extends GameObjectFactory {
    @Override
    public GameObject createEnemy() {
        return new KnightEnemy();
    }
    
    @Override
    public GameObject createPlayer() {
        return new KnightPlayer();
    }
    
    @Override
    public GameObject createItem() {
        return new SwordItem();
    }
    
    @Override
    protected GameObject instantiateGameObject(String type) {
        // 具体的实例化逻辑
        switch (type) {
            case "knight":
                return new KnightEnemy();
            case "archer":
                return new ArcherEnemy();
            default:
                return new DefaultGameObject();
        }
    }
}

4. 报表系统

// 报表工厂
public interface ReportFactory {
    Report createReport(String reportType);
    Report createReport(ReportRequest request);
    
    // 默认方法
    default Report createDefaultReport() {
        return new SimpleReport();
    }
}

// 具体报表工厂
public class FinancialReportFactory implements ReportFactory {
    @Override
    public Report createReport(String reportType) {
        switch (reportType.toUpperCase()) {
            case "BALANCE_SHEET":
                return new BalanceSheetReport();
            case "INCOME_STATEMENT":
                return new IncomeStatementReport();
            case "CASH_FLOW":
                return new CashFlowReport();
            default:
                throw new IllegalArgumentException("未知的报表类型: " + reportType);
        }
    }
    
    @Override
    public Report createReport(ReportRequest request) {
        Report report = createReport(request.getType());
        report.setParameters(request.getParameters());
        report.generate();
        return report;
    }
}

四、优缺点深度解析

优点

  1. 符合开闭原则

    • 添加新产品时,只需添加新的具体工厂和产品类
    • 不需要修改现有代码
    • 系统扩展性好
  2. 单一职责原则

    • 每个具体工厂只负责创建一种产品
    • 产品创建逻辑集中管理
    • 便于维护和测试
  3. 依赖倒置原则

    • 客户端只依赖抽象接口
    • 不依赖具体实现
    • 降低耦合度
  4. 良好的封装性

    • 隐藏产品创建细节
    • 客户端不需要知道具体产品类
    • 实现细节可以独立变化
  5. 代码可复用性高

    • 工厂方法可以复用
    • 具体工厂可以继承和扩展
    • 模板方法提供了通用框架

缺点

  1. 类数量增加

    • 每个产品都需要一个具体工厂
    • 系统复杂度增加
    • 代码量增大
  2. 设计复杂度高

    • 需要设计抽象层
    • 理解成本较高
    • 可能过度设计
  3. 客户端代码复杂

    • 需要知道具体工厂类
    • 选择合适工厂的逻辑可能复杂
    • 增加了使用难度
  4. 性能开销

    • 额外的抽象层带来性能开销
    • 对象创建可能需要多次方法调用
    • 对性能敏感场景不友好
  5. 扩展新产品困难

    • 添加新产品需要修改抽象工厂接口
    • 所有具体工厂都需要实现新方法
    • 可能违反开闭原则

五、使用要点与最佳实践

1. 简单工厂vs工厂方法vs抽象工厂

// 选择指南
public class FactoryPatternSelector {
    /*
     * 使用简单工厂模式当:
     * 1. 产品种类较少
     * 2. 不经常添加新产品
     * 3. 客户端不关心具体产品
     * 
     * 使用工厂方法模式当:
     * 1. 无法预知创建哪些具体产品
     * 2. 希望扩展性更好
     * 3. 需要将产品创建延迟到子类
     * 
     * 使用抽象工厂模式当:
     * 1. 需要创建产品族
     * 2. 需要保证产品兼容性
     * 3. 有多个产品等级结构
     */
}

2. 静态工厂方法

// 静态工厂方法
public class StaticFactory {
    // 私有构造方法
    private StaticFactory() {}
    
    // 静态工厂方法
    public static Product createProduct(String type) {
        switch (type.toLowerCase()) {
            case "a":
                return new ConcreteProductA();
            case "b":
                return new ConcreteProductB();
            case "c":
                return new ConcreteProductC();
            default:
                throw new IllegalArgumentException("未知的产品类型: " + type);
        }
    }
    
    // 命名工厂方法
    public static Product createProductA() {
        return new ConcreteProductA();
    }
    
    public static Product createProductB() {
        return new ConcreteProductB();
    }
    
    public static Product createProductC() {
        return new ConcreteProductC();
    }
    
    // 缓存实例
    private static final Map<String, Product> cache = new ConcurrentHashMap<>();
    
    public static Product getCachedProduct(String type) {
        return cache.computeIfAbsent(type, StaticFactory::createProduct);
    }
}

// 使用静态工厂
class StaticFactoryClient {
    public static void main(String[] args) {
        Product productA = StaticFactory.createProduct("a");
        Product productB = StaticFactory.createProductB();
        Product cached = StaticFactory.getCachedProduct("c");
    }
}

3. 依赖注入结合

// 依赖注入 + 工厂方法
@Component
public class ServiceFactory {
    private final Map<String, Service> serviceMap = new HashMap<>();
    
    @Autowired
    public ServiceFactory(List<Service> services) {
        for (Service service : services) {
            serviceMap.put(service.getType(), service);
        }
    }
    
    public Service getService(String type) {
        Service service = serviceMap.get(type);
        if (service == null) {
            throw new IllegalArgumentException("未知的服务类型: " + type);
        }
        return service;
    }
    
    // 工厂方法
    public Service createService(String type) {
        Service prototype = getService(type);
        return prototype.clone(); // 原型模式结合
    }
}

// 配置类
@Configuration
public class FactoryConfig {
    @Bean
    @Scope("prototype")
    public Product productA() {
        return new ConcreteProductA();
    }
    
    @Bean
    @Scope("prototype")
    public Product productB() {
        return new ConcreteProductB();
    }
    
    @Bean
    public ProductFactory productFactory() {
        return new ProductFactory();
    }
}

// 工厂类
public class ProductFactory {
    @Autowired
    private ApplicationContext context;
    
    public Product getProduct(String type) {
        return context.getBean(type, Product.class);
    }
}

4. 泛型工厂方法

// 泛型工厂
public interface GenericFactory<T> {
    T create();
    
    default List<T> createMultiple(int count) {
        List<T> result = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            result.add(create());
        }
        return result;
    }
}

// 具体泛型工厂
public class ProductFactory<T extends Product> implements GenericFactory<T> {
    private final Class<T> productClass;
    
    public ProductFactory(Class<T> productClass) {
        this.productClass = productClass;
    }
    
    @Override
    public T create() {
        try {
            return productClass.newInstance();
        } catch (Exception e) {
            throw new RuntimeException("创建产品失败", e);
        }
    }
}

// 使用泛型工厂
class GenericFactoryClient {
    public static void main(String[] args) {
        GenericFactory<ConcreteProductA> factoryA = 
            new ProductFactory<>(ConcreteProductA.class);
        
        ConcreteProductA productA = factoryA.create();
        List<ConcreteProductA> products = factoryA.createMultiple(5);
    }
}

5. 工厂方法的高级用法

// 1. 带缓存的工厂
public class CachedFactory<T> implements GenericFactory<T> {
    private final GenericFactory<T> delegate;
    private final Cache<String, T> cache;
    
    public CachedFactory(GenericFactory<T> delegate) {
        this.delegate = delegate;
        this.cache = CacheBuilder.newBuilder()
            .maximumSize(100)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build();
    }
    
    @Override
    public T create() {
        return delegate.create();
    }
    
    public T getOrCreate(String key, Callable<T> loader) {
        try {
            return cache.get(key, loader);
        } catch (Exception e) {
            throw new RuntimeException("创建缓存对象失败", e);
        }
    }
}

// 2. 组合工厂
public class CompositeFactory<T> implements GenericFactory<T> {
    private final List<GenericFactory<T>> factories = new ArrayList<>();
    
    public void addFactory(GenericFactory<T> factory) {
        factories.add(factory);
    }
    
    @Override
    public T create() {
        for (GenericFactory<T> factory : factories) {
            try {
                return factory.create();
            } catch (Exception e) {
                // 这个工厂失败,尝试下一个
            }
        }
        throw new RuntimeException("所有工厂都创建失败");
    }
}

// 3. 装饰器工厂
public abstract class FactoryDecorator<T> implements GenericFactory<T> {
    protected final GenericFactory<T> decoratedFactory;
    
    public FactoryDecorator(GenericFactory<T> decoratedFactory) {
        this.decoratedFactory = decoratedFactory;
    }
    
    @Override
    public T create() {
        T product = decoratedFactory.create();
        decorate(product);
        return product;
    }
    
    protected abstract void decorate(T product);
}

// 具体装饰器
public class ValidatingFactory<T extends Product> extends FactoryDecorator<T> {
    public ValidatingFactory(GenericFactory<T> decoratedFactory) {
        super(decoratedFactory);
    }
    
    @Override
    protected void decorate(T product) {
        validate(product);
    }
    
    private void validate(T product) {
        if (product == null) {
            throw new IllegalArgumentException("产品不能为null");
        }
        // 更多验证逻辑...
    }
}

6. 测试策略

// 工厂方法测试
@ExtendWith(MockitoExtension.class)
class FactoryMethodTest {
    
    @Test
    void testProductCreation() {
        // 测试基本工厂方法
        Creator creator = new ConcreteCreatorA();
        Product product = creator.createProduct();
        
        assertNotNull(product, "产品不应为null");
        assertEquals("ProductA", product.getName(), "产品名称应匹配");
        
        // 测试操作
        assertDoesNotThrow(() -> product.operation());
    }
    
    @Test
    void testFactoryMethodWithParameter() {
        // 测试参数化工厂
        ParameterizedCreator creator = new ParameterizedCreator("a");
        Product productA = creator.createProduct();
        assertTrue(productA instanceof ConcreteProductA, "应创建产品A");
        
        creator.setProductType("b");
        Product productB = creator.createProduct();
        assertTrue(productB instanceof ConcreteProductB, "应创建产品B");
        
        // 测试无效参数
        assertThrows(IllegalArgumentException.class, () -> {
            creator.setProductType("invalid");
            creator.createProduct();
        });
    }
    
    @Test
    void testTemplateMethod() {
        // 测试模板方法
        ConcreteCreatorA creator = new ConcreteCreatorA();
        
        // 验证钩子方法
        assertFalse(creator.shouldLog(), "创建者A不应记录日志");
        
        // 验证模板方法执行
        assertDoesNotThrow(() -> creator.operation());
        assertDoesNotThrow(() -> creator.operationWithHook());
    }
    
    @Test
    void testPerformance() {
        // 性能测试
        Creator creator = new ConcreteCreatorA();
        
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            creator.createProduct();
        }
        long duration = System.currentTimeMillis() - startTime;
        
        assertTrue(duration < 1000, "创建10000个产品应在1秒内完成");
    }
    
    @Test
    void testThreadSafety() throws InterruptedException {
        // 线程安全测试
        int threadCount = 10;
        ExecutorService executor = Executors.newFixedThreadPool(threadCount);
        Creator creator = new ConcreteCreatorA();
        List<Future<Product>> futures = new ArrayList<>();
        
        for (int i = 0; i < threadCount; i++) {
            futures.add(executor.submit(creator::createProduct));
        }
        
        // 验证所有产品都已创建
        for (Future<Product> future : futures) {
            assertDoesNotThrow(future::get);
        }
        
        executor.shutdown();
        assertTrue(executor.awaitTermination(5, TimeUnit.SECONDS));
    }
    
    @Test
    void testFactoryMethodInFramework() {
        // 模拟Spring框架集成测试
        ApplicationContext context = mock(ApplicationContext.class);
        when(context.getBean(Product.class)).thenReturn(new ConcreteProductA());
        
        ProductFactory factory = new ProductFactory();
        // 这里需要注入context...
        
        // 验证工厂方法
        Product product = factory.getProduct("productA");
        assertNotNull(product);
    }
}

六、与其他模式的比较

模式相似点不同点适用场景
简单工厂都用于创建对象简单工厂集中创建,工厂方法分散到子类产品较少用简单工厂,需要扩展用工厂方法
抽象工厂都通过工厂创建对象抽象工厂创建产品族,工厂方法创建单一产品需要产品族用抽象工厂,单一产品用工厂方法
模板方法都使用继承模板方法定义算法骨架,工厂方法定义对象创建算法流程用模板方法,对象创建用工厂方法
原型都创建对象原型通过复制,工厂方法通过工厂创建已有相似对象用原型,需要灵活创建用工厂方法

七、实际应用示例

示例1:Java标准库中的工厂方法

// Java标准库中的工厂方法
public class JavaStandardLibraryExamples {
    public static void main(String[] args) {
        // 1. Calendar.getInstance() - 工厂方法
        Calendar calendar = Calendar.getInstance();
        System.out.println("Calendar实例: " + calendar.getClass().getName());
        
        // 2. NumberFormat.getInstance() - 工厂方法
        NumberFormat numberFormat = NumberFormat.getInstance();
        NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
        NumberFormat percentFormat = NumberFormat.getPercentInstance();
        
        // 3. Collections.unmodifiableList() - 静态工厂方法
        List<String> list = new ArrayList<>();
        List<String> unmodifiableList = Collections.unmodifiableList(list);
        
        // 4. Executors.newFixedThreadPool() - 工厂方法
        ExecutorService executor = Executors.newFixedThreadPool(10);
        ExecutorService cachedExecutor = Executors.newCachedThreadPool();
        ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(5);
        
        // 5. DateTimeFormatter.ofPattern() - 工厂方法
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        
        // 6. SSLContext.getInstance() - 工厂方法
        try {
            SSLContext sslContext = SSLContext.getInstance("TLS");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        
        // 7. URL.openConnection() - 工厂方法
        try {
            URL url = new URL("https://example.com");
            URLConnection connection = url.openConnection();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 8. ServiceLoader.load() - 工厂方法
        ServiceLoader<Driver> drivers = ServiceLoader.load(Driver.class);
    }
}

示例2:Spring框架中的工厂方法

// Spring中的工厂方法模式
@Configuration
public class AppConfig {
    
    // 工厂方法Bean
    @Bean
    public DataSource dataSource() {
        return DataSourceBuilder.create()
                .url("jdbc:mysql://localhost:3306/mydb")
                .username("root")
                .password("password")
                .build();
    }
    
    // 工厂方法Bean
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
        LocalContainerEntityManagerFactoryBean factory = 
            new LocalContainerEntityManagerFactoryBean();
        factory.setDataSource(dataSource);
        factory.setJpaVendorAdapter(jpaVendorAdapter);
        factory.setPackagesToScan("com.example.entity");
        return factory;
    }
    
    // 工厂Bean
    @Bean
    public FactoryBean<MyService> myServiceFactory() {
        return new FactoryBean<MyService>() {
            @Override
            public MyService getObject() {
                return new MyServiceImpl();
            }
            
            @Override
            public Class<?> getObjectType() {
                return MyService.class;
            }
            
            @Override
            public boolean isSingleton() {
                return true;
            }
        };
    }
}

// 自定义工厂Bean
@Component
public class ProductFactoryBean implements FactoryBean<Product> {
    private String productType;
    
    public void setProductType(String productType) {
        this.productType = productType;
    }
    
    @Override
    public Product getObject() {
        switch (productType) {
            case "A": return new ConcreteProductA();
            case "B": return new ConcreteProductB();
            default: throw new IllegalArgumentException("未知的产品类型");
        }
    }
    
    @Override
    public Class<?> getObjectType() {
        return Product.class;
    }
    
    @Override
    public boolean isSingleton() {
        return false; // 每次返回新实例
    }
}

八、注意事项

  1. 避免过度使用:简单对象不需要工厂方法
  2. 合理选择模式:根据场景选择简单工厂、工厂方法或抽象工厂
  3. 保持接口稳定:工厂方法接口应保持稳定
  4. 考虑线程安全:多线程环境需要特殊处理
  5. 合理使用缓存:对创建成本高的对象使用缓存
  6. 文档化:明确每个工厂方法创建的产品类型
  7. 错误处理:提供清晰的错误信息和异常
  8. 性能考虑:避免在工厂方法中执行昂贵操作

九、总结

工厂方法模式是一种灵活的对象创建模式,特别适用于:

  • 无法预知需要创建的具体类
  • 希望将产品创建延迟到子类
  • 需要扩展新产品类型
  • 框架开发,希望用户扩展功能

工厂方法模式的核心优势

  1. 良好的扩展性:添加新产品不影响现有代码
  2. 符合开闭原则:对扩展开放,对修改关闭
  3. 降低耦合:客户端只依赖抽象接口
  4. 提高可维护性:产品创建逻辑集中管理

最佳实践建议

  1. 合理使用继承:工厂方法通常与继承一起使用
  2. 结合模板方法:在父类中定义算法骨架
  3. 使用钩子方法:提供扩展点
  4. 考虑性能优化:对频繁创建的对象使用缓存
  5. 完善错误处理:提供清晰的错误信息
  6. 编写充分测试:确保工厂方法正确工作

工厂方法模式是框架设计和可扩展系统的重要工具,在Java生态中有广泛应用。掌握工厂方法模式可以帮助你编写出更灵活、可维护和可扩展的代码。