一、模式定义
工厂方法模式是一种创建型设计模式,它定义了一个创建对象的接口,但由子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类。
二、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. 简单工厂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; // 每次返回新实例
}
}
八、注意事项
- 避免过度使用:简单对象不需要工厂方法
- 合理选择模式:根据场景选择简单工厂、工厂方法或抽象工厂
- 保持接口稳定:工厂方法接口应保持稳定
- 考虑线程安全:多线程环境需要特殊处理
- 合理使用缓存:对创建成本高的对象使用缓存
- 文档化:明确每个工厂方法创建的产品类型
- 错误处理:提供清晰的错误信息和异常
- 性能考虑:避免在工厂方法中执行昂贵操作
九、总结
工厂方法模式是一种灵活的对象创建模式,特别适用于:
- 无法预知需要创建的具体类
- 希望将产品创建延迟到子类
- 需要扩展新产品类型
- 框架开发,希望用户扩展功能
工厂方法模式的核心优势:
- 良好的扩展性:添加新产品不影响现有代码
- 符合开闭原则:对扩展开放,对修改关闭
- 降低耦合:客户端只依赖抽象接口
- 提高可维护性:产品创建逻辑集中管理
最佳实践建议:
- 合理使用继承:工厂方法通常与继承一起使用
- 结合模板方法:在父类中定义算法骨架
- 使用钩子方法:提供扩展点
- 考虑性能优化:对频繁创建的对象使用缓存
- 完善错误处理:提供清晰的错误信息
- 编写充分测试:确保工厂方法正确工作
工厂方法模式是框架设计和可扩展系统的重要工具,在Java生态中有广泛应用。掌握工厂方法模式可以帮助你编写出更灵活、可维护和可扩展的代码。