在 Spring Boot 日常开发中,工厂方法模式(Factory Method Pattern)的应用场景非常多,它可以帮助我们优雅地创建对象,解耦对象创建逻辑,提高代码的可维护性和可扩展性。下面我将详细列举几个典型的应用场景,并提供具体的代码示例。
场景一: 创建不同类型的日志记录器 (Logger)
假设你的 Spring Boot 应用需要支持多种日志记录方式,例如:
- 控制台日志 (Console Logger)
- 文件日志 (File Logger)
- 数据库日志 (Database Logger)
- 远程日志 (Remote Logger,例如发送到 Logstash 或 Kafka)
你可以使用工厂方法模式来创建不同类型的 Logger 对象。
1. 定义 Logger 接口:
public interface Logger {
void log(String message);
}
2. 创建具体的 Logger 实现类:
// 控制台日志
public class ConsoleLogger implements Logger {
@Override
public void log(String message) {
System.out.println("[Console] " + message);
}
}
// 文件日志
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class FileLogger implements Logger {
private final String logFilePath;
public FileLogger(String logFilePath) {
this.logFilePath = logFilePath;
}
@Override
public void log(String message) {
try (PrintWriter writer = new PrintWriter(new FileWriter(logFilePath, true))) {
writer.println("[File] " + message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 数据库日志 (示例,省略具体数据库操作)
public class DatabaseLogger implements Logger {
@Override
public void log(String message) {
System.out.println("[Database] " + message); // 实际应用中会写入数据库
// ... 数据库写入逻辑 ...
}
}
3. 定义 Logger 工厂接口:
public interface LoggerFactory {
Logger createLogger();
}
4. 创建具体的 Logger 工厂类:
// 控制台日志工厂
public class ConsoleLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new ConsoleLogger();
}
}
// 文件日志工厂
public class FileLoggerFactory implements LoggerFactory {
private final String logFilePath;
public FileLoggerFactory(String logFilePath) {
this.logFilePath = logFilePath;
}
@Override
public Logger createLogger() {
return new FileLogger(logFilePath);
}
}
// 数据库日志工厂
public class DatabaseLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new DatabaseLogger();
}
}
5. 在 Spring Boot 中配置和使用:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@SpringBootApplication
public class LoggerFactoryExampleApplication implements CommandLineRunner {
// 使用 @Qualifier 注解指定要注入的 LoggerFactory 实现
@Autowired
@Qualifier("fileLoggerFactory") // 或者 "consoleLoggerFactory", "databaseLoggerFactory"
private LoggerFactory loggerFactory;
public static void main(String[] args) {
SpringApplication.run(LoggerFactoryExampleApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
Logger logger = loggerFactory.createLogger(); // 通过工厂创建 Logger
logger.log("This is a log message.");
}
}
@Configuration
class AppConfig {
// 将 LoggerFactory 的实现类注册为 Spring Bean
@Bean
public LoggerFactory fileLoggerFactory() {
return new FileLoggerFactory("app.log"); // 指定日志文件路径
}
@Bean
public LoggerFactory consoleLoggerFactory() {
return new ConsoleLoggerFactory();
}
@Bean
public LoggerFactory databaseLoggerFactory() {
return new DatabaseLoggerFactory();
}
}
解释:
- 我们定义了
Logger
接口和三个具体的Logger
实现类。 - 我们定义了
LoggerFactory
接口和三个具体的LoggerFactory
实现类,分别用于创建不同类型的Logger
。 - 在 Spring Boot 配置类 (
AppConfig
) 中,我们使用@Bean
注解将FileLoggerFactory
注册为 Spring Bean。 - 在
LoggerFactoryExampleApplication
中,我们通过@Autowired
和@Qualifier
注解注入LoggerFactory
的实例(这里注入的是FileLoggerFactory
)。 - 在
run
方法中,我们通过loggerFactory.createLogger()
方法创建Logger
对象,并调用其log()
方法。
好处:
- 解耦: 应用程序代码不依赖于具体的
Logger
实现类,而是依赖于Logger
接口和LoggerFactory
接口。 - 可扩展: 如果要添加新的日志记录方式(例如,发送到远程日志服务器),只需要创建一个新的
Logger
实现类和一个对应的LoggerFactory
实现类,并在 Spring Boot 配置中注册新的LoggerFactory
Bean 即可,无需修改现有代码。 - 可配置: 可以通过配置文件或
@Qualifier
注解轻松切换不同的Logger
实现。
场景二: 创建不同类型的支付方式 (Payment Method)
假设你的电商应用需要支持多种支付方式,例如:
- 支付宝支付 (Alipay)
- 微信支付 (WeChat Pay)
- 银联支付 (UnionPay)
你可以使用工厂方法模式来创建不同类型的 Payment
对象。
1. 定义 Payment 接口:
public interface Payment {
void pay(double amount);
}
2. 创建具体的 Payment 实现类:
// 支付宝支付
public class Alipay implements Payment {
@Override
public void pay(double amount) {
System.out.println("Paying " + amount + " via Alipay...");
// ... 支付宝支付的具体逻辑 ...
}
}
// 微信支付
public class WeChatPay implements Payment {
@Override
public void pay(double amount) {
System.out.println("Paying " + amount + " via WeChat Pay...");
// ... 微信支付的具体逻辑 ...
}
}
3. 定义 Payment 工厂接口:
public interface PaymentFactory {
Payment createPayment();
}
4. 创建具体的 Payment 工厂类:
// 支付宝支付工厂
public class AlipayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new Alipay();
}
}
// 微信支付工厂
public class WeChatPayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new WeChatPay();
}
}
5. 在 Spring Boot 中配置和使用:
类似于Logger的例子,此处省略。 只需把Logger替换成Payment即可。
场景三: 创建不同类型的数据库连接 (Database Connection)
- 定义
Connection
接口,表示数据库连接。 - 创建不同的
Connection
实现类,例如MySQLConnection
,PostgreSQLConnection
,OracleConnection
。 - 定义
ConnectionFactory
接口,包含createConnection()
方法。 - 创建不同的
ConnectionFactory
实现类,例如MySQLConnectionFactory
,PostgreSQLConnectionFactory
,OracleConnectionFactory
,分别用于创建不同类型的数据库连接。 - 在Spring Boot中使用
@Configuration
和@Bean
将具体的ConnectionFactory
注册为Bean.
场景四: 创建不同类型的消息发送器 (Message Sender)
- 定义
MessageSender
接口,表示消息发送器。 - 创建不同的
MessageSender
实现类,例如EmailSender
,SmsSender
,WeChatSender
。 - 定义
MessageSenderFactory
接口,包含createSender()
方法。 - 创建不同的
MessageSenderFactory
实现类,例如EmailSenderFactory
,SmsSenderFactory
,WeChatSenderFactory
,分别用于创建不同类型的消息发送器。 - 在Spring Boot中使用
@Configuration
和@Bean
将具体的MessageSenderFactory
注册为Bean.
总结
工厂方法模式在 Spring Boot 日常开发中非常有用,它可以应用于各种需要创建不同类型对象的场景。 通过使用工厂方法模式,你可以:
- 解耦对象的创建逻辑和使用逻辑。
- 提高代码的可维护性和可扩展性。
- 轻松地切换不同的对象实现。
- 符合开闭原则。
在 Spring Boot 中,我们可以结合 Spring 的依赖注入、@Configuration
和 @Bean
注解,更方便地使用工厂方法模式。