请编写一个工厂方法模式的实际应用案例代码。
参考回答
问题:编写一个工厂方法模式的实际应用案例代码。
// 产品接口
interface Product {
void use();
}
// 具体产品A
class ProductA implements Product {
@Override
public void use() {
System.out.println("使用产品A");
}
}
// 具体产品B
class ProductB implements Product {
@Override
public void use() {
System.out.println("使用产品B");
}
}
// 抽象工厂
abstract class ProductFactory {
public abstract Product createProduct();
}
// 具体工厂A
class ProductAFactory extends ProductFactory {
@Override
public Product createProduct() {
return new ProductA();
}
}
// 具体工厂B
class ProductBFactory extends ProductFactory {
@Override
public Product createProduct() {
return new ProductB();
}
}
// 客户端
public class FactoryMethodExample {
public static void main(String[] args) {
ProductFactory factoryA = new ProductAFactory();
Product productA = factoryA.createProduct();
productA.use();
ProductFactory factoryB = new ProductBFactory();
Product productB = factoryB.createProduct();
productB.use();
}
}
详细讲解与拓展
1. 工厂方法模式的结构
- 产品接口(Product):定义了所有具体产品的公共接口,客户端通过该接口与具体产品进行交互。
- 具体产品(ProductA 和 ProductB):实现了产品接口,提供具体的实现。
- 抽象工厂(ProductFactory):定义了一个抽象方法
createProduct(),该方法用于创建产品。 - 具体工厂(ProductAFactory 和 ProductBFactory):每个具体工厂负责创建一种具体产品,并实现
createProduct()方法。 - 客户端(FactoryMethodExample):客户端通过具体工厂获取产品实例,调用产品的方法。
2. 核心思想
工厂方法模式将产品的创建推迟到子类中进行处理,客户端不再关心具体的产品类型,而是通过调用工厂方法来获取产品实例。每个具体工厂类负责创建一种特定的产品,子类化工厂类便于扩展更多类型的产品。
3. 优点
– 符合开放封闭原则:新增产品只需要扩展新的工厂,而不需要修改现有的代码。
– 避免了在客户端中直接创建产品:客户端只需要依赖抽象工厂,而不需要知道具体产品类的名称。
– 提高了灵活性和可维护性:当产品类变动时,客户端无需调整,只需在工厂类中做修改。
4. 缺点
– 类的数量增加:为了每种产品都创建一个工厂类,会使得系统中的类的数量增加,增加了代码的复杂性。
– 适用于产品变化较少的场景:如果产品种类变化频繁,工厂类也需要不断扩展,这在某些场景下可能会带来额外的工作量。
5. 扩展
– 抽象工厂模式:如果系统需要创建一系列相关的产品,而不仅仅是单个产品时,可以扩展为抽象工厂模式。抽象工厂会提供多个工厂方法,每个工厂方法负责创建一个系列的产品。
– 工厂方法与简单工厂的对比:简单工厂模式是通过一个工厂类来创建所有产品,而工厂方法模式则通过多个具体工厂类来处理不同产品的创建,灵活性更高。
举个例子:
假设我们开发一个日志系统,支持多种日志记录方式(文件日志、控制台日志)。我们可以使用工厂方法模式来管理不同类型的日志对象:
// 日志接口
interface Logger {
void log(String message);
}
// 具体日志:文件日志
class FileLogger implements Logger {
@Override
public void log(String message) {
System.out.println("写入文件日志: " + message);
}
}
// 具体日志:控制台日志
class ConsoleLogger implements Logger {
@Override
public void log(String message) {
System.out.println("输出控制台日志: " + message);
}
}
// 抽象日志工厂
abstract class LoggerFactory {
public abstract Logger createLogger();
}
// 具体工厂:文件日志工厂
class FileLoggerFactory extends LoggerFactory {
@Override
public Logger createLogger() {
return new FileLogger();
}
}
// 具体工厂:控制台日志工厂
class ConsoleLoggerFactory extends LoggerFactory {
@Override
public Logger createLogger() {
return new ConsoleLogger();
}
}
// 客户端
public class LoggerFactoryExample {
public static void main(String[] args) {
LoggerFactory fileLoggerFactory = new FileLoggerFactory();
Logger fileLogger = fileLoggerFactory.createLogger();
fileLogger.log("文件日志测试");
LoggerFactory consoleLoggerFactory = new ConsoleLoggerFactory();
Logger consoleLogger = consoleLoggerFactory.createLogger();
consoleLogger.log("控制台日志测试");
}
}
在这个例子中,LoggerFactory 是抽象工厂类,而 FileLoggerFactory 和 ConsoleLoggerFactory 是具体工厂类。每个具体工厂负责创建不同类型的日志记录器。客户端通过具体工厂获取相应的日志对象并调用其方法。
总结
工厂方法模式是创建型模式的一种,通过将产品的创建过程延迟到子类中来实现产品的多样化,避免了客户端直接依赖具体的产品类。它符合开放封闭原则,适用于产品种类不频繁变化的场景。然而,它会增加系统中的类数量,在产品种类增加时可能会导致工厂类的数量过多。