设计模式 - Factory Method 工厂方法

定义

工厂方法模式是一种创建型设计模式, 又称为工厂模式。其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。

也就是说它定义了一个创建对象的接口,但将具体实例化操作推迟到子类中。也就是说,父类提供创建对象的方法, 并且允许子类决定实例化对象的类型。这样做的好处是可以使一个类的实例化延迟到其子类中进行,从而提供更大的灵活性和扩展性。

    和模板方法的定义有一点像。但是工厂方法着重于对象的创建过程,它提供了一种灵活的实例化策略;而模板方法则专注于定义算法的框架,将固定不变的“模板”放在父类,变化的部分放在子类中,由子类去实现。
    所以当需要控制对象的创建过程,尤其是当类型的选择依赖于运行时信息时,应考虑使用工厂方法。而当多个类有相似的操作流程,但部分步骤需要定制时,模板方法是更合适的选择。

工厂的实现构成

构成

  1. 产品接口(Product Interface):定义了所有具体产品需要实现的接口或抽象类,规范了产品的公共接口。
  2. 具体产品类(Concrete Product):实现了产品接口的具体类,不同的具体产品代表不同的产品种类。
  3. 工厂接口(Factory Interface):声明了一个创建产品对象的方法,但不负责实际的产品创建,而是交由它的实现类去完成。
  4. 具体工厂类(Concrete Factory):实现了工厂接口,负责实例化具体的产品对象。每个具体工厂类都与一种具体产品类相对应,负责创建该类型的产品对象。

UML图

在这里插入图片描述

工厂方法的代码实现

产品接口:
// 产品接口:日志记录器接口
interface Logger {
    void log(String message);
}
具体产品类:
// 具体产品类:文件日志记录器
class FileLogger implements Logger {
    public void log(String message) {
        System.out.println("File: " + message);
    }
}

// 具体产品类:数据库日志记录器
class DatabaseLogger implements Logger {
    public void log(String message) {
        System.out.println("Database: " + message);
    }
}
工厂接口:
// 工厂接口
interface LoggerFactory {
    Logger createLogger();
}
具体工厂类:
// 具体工厂类:文件日志记录器工厂
class FileLoggerFactory implements LoggerFactory {
    public Logger createLogger() {
        return new FileLogger();
    }
}

// 具体工厂类:数据库日志记录器工厂
class DatabaseLoggerFactory implements LoggerFactory {
    public Logger createLogger() {
        return new DatabaseLogger();
    }
}
客户端代码:
public class Client {
    public static void main(String[] args) {
        // 动态选择日志记录器工厂,可以通过配置或其他逻辑来决定使用哪种工厂
        LoggerFactory factory;
        String loggerType = "database"; // 可以从配置文件或其他地方读取这个值

        if ("file".equalsIgnoreCase(loggerType)) {
            factory = new FileLoggerFactory();
        } else if ("database".equalsIgnoreCase(loggerType)) {
            factory = new DatabaseLoggerFactory();
        } else {
            throw new IllegalArgumentException("Unknown logger type: " + loggerType);
        }

        // 使用工厂创建日志记录器
        Logger logger = factory.createLogger();
        logger.log("A log message");
    }
}

总结

优点

  1. 解耦:将具体产品的创建和使用分离,使得系统更易于扩展和维护。
  2. 灵活性:可以引入新的产品子类而不修改现有代码,符合开闭原则。
  3. 单一职责原则:每个具体工厂负责创建相应的产品,职责单一明确。

缺点

  1. 增加代码复杂度:需要定义多个子类来实现工厂方法,增加了系统的复杂度。
  2. 类爆炸问题:对于每一种产品都需要一个对应的工厂类,可能导致类的数量急剧增加。

应用场景

  1. 需要创建复杂对象:如果创建对象的过程比较复杂,可以使用工厂方法将对象的创建过程封装起来。
  2. 具体类型在运行时决定:如果程序的具体类型需要在运行时才能确定,工厂方法是一个很好的选择。
  3. 解耦:希望将程序的创建和使用,减少耦合,提高系统的灵活性和可维护性。
  4. 系统未来可能需要引入新的功能类别:工厂方法可以方便地引入新产品而不影响现有系统。

简单工厂、工厂方法和抽象工厂的区别

  1. 简单工厂:一个工厂方法用来创建不同类型的对象
  2. 工厂方法:一个具体的工厂类创建一个对应的具体对象
  3. 抽象工厂:一个具体的工厂类创建一系列相关的对象

其他设计模式文章:

  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值