工厂方法模式 (Factory Method Pattern)

定义:

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,用于解决对象创建的问题。它定义了一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

工厂方法模式的关键组成部分包括:

  1. 抽象创建者(Creator)
    • 定义了一个工厂方法,通常是一个抽象方法,用于创建产品对象。创建者通常包含依赖于抽象产品的代码。
  2. 具体创建者(Concrete Creator)
    • 实现了抽象创建者定义的工厂方法,用于返回一个具体产品的实例。每个具体创建者都负责创建一个特定类型的产品。
  3. 抽象产品(Product)
    • 定义了产品的接口。在抽象创建者的代码中,所有对产品的引用都使用这个接口。
  4. 具体产品(Concrete Product)
    • 实现了抽象产品定义的接口。工厂方法返回的产品实例实际上是某个具体产品对象。
解决的问题:
  • 创建对象的灵活性
    • 当一个类不知道它所必须创建的对象的类的时候。工厂方法模式允许类把实例化延迟到子类进行,这提供了更大的灵活性。
  • 产品类扩展的便利性
    • 当一个类希望由其子类来指定创建的对象时。通过定义工厂方法,子类可以覆盖这个方法以改变创建对象的类型。
  • 解耦产品的具体实现和创建过程
    • 工厂方法模式使得客户代码与产品的具体实现解耦,客户代码通过工厂接口创建产品,无需关心产品的具体实现。
  • 单一职责原则
    • 工厂方法模式可以将产品的创建职责集中到不同的工厂类中,每个工厂类负责创建一种具体产品,这符合单一职责原则。
  • 开闭原则
    • 系统更容易扩展,可以引入新的具体产品和具体工厂类,而无需修改现有代码。这符合开闭原则,即对扩展开放,对修改封闭
使用场景:
  • 不同环境下创建不同实例
    • 当对象的创建需要基于不同的环境或条件时,例如不同的配置、操作系统或者不同的资源要求。
  • 明确分离客户端和产品实现
    • 当需要明确区分客户端和产品的具体实现,使得客户端不依赖于产品实现的具体类时。
  • 单个类负责多个不同对象的创建
    • 当一个类需要创建多种类型的对象,且这些对象有共同的基类或接口时,但同时又需要保持类的职责单一。
  • 扩展产品类时避免影响客户端
    • 当系统要求提供扩展产品类的能力,而不希望这些更改影响到已有的客户端代码时。
  • 需要封装对象的创建过程
    • 当对象的创建过程需要被封装起来,以便提供更多的复用性和灵活性时。
  • 类的实例化过程复杂或有特殊要求
    • 当创建对象的过程很复杂,如涉及到复杂的初始化步骤,或者需要进行资源回收等。
示例代码:
// 产品接口
public interface Product {
    void use();
}

// 具体产品
public class ConcreteProductA implements Product {
    @Override
    public void use() {
        System.out.println("Using ConcreteProductA");
    }
}

public class ConcreteProductB implements Product {
    @Override
    public void use() {
        System.out.println("Using ConcreteProductB");
    }
}

// 创建者/工厂接口
public interface Factory {
    Product createProduct();
}

// 具体创建者/工厂
public class ConcreteFactoryA implements Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

public class ConcreteFactoryB implements Factory {
    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}
主要符合的设计原则:
  1. 开闭原则(Open-Closed Principle):
    • 工厂方法模式非常符合开闭原则。它允许系统在不修改现有代码的情况下引入新的产品类型。当系统需要扩展新的产品时,只需要添加相应的具体工厂类和产品类即可。
  2. 单一职责原则(Single Responsibility Principle):
    • 在工厂方法模式中,每个具体工厂类只负责创建单一类型的产品。这符合单一职责原则,因为每个类都只负责一个具体的创建任务。
  3. 依赖倒转原则(Dependency Inversion Principle):
    • 工厂方法模式实现了依赖倒转原则,因为客户代码依赖于抽象接口(产品接口和工厂接口),而不是具体的类实现。这意味着客户代码并不依赖于具体的产品实例化逻辑。

工厂方法模式通过定义一个用于创建对象的接口,让子类决定实例化哪个类,从而使一个类的实例化延迟到其子类,提高了代码的灵活性和可扩展性。同时,它支持良好的封装性,客户代码仅通过接口与工厂交互,无需关心具体的产品实现细节。

在JDK中的应用:
  • java.util.Calendar
    • Calendar.getInstance() 是一个工厂方法,它根据当前的时间和默认时区返回一个 Calendar 的具体实例。此方法隐藏了具体 Calendar 子类的创建细节。
  • java.util.ResourceBundle
    • ResourceBundle.getBundle() 方法是一个工厂方法,用于根据给定的基础名和目标区域设置加载资源束。这个方法封装了资源束对象的选择和加载过程。
  • java.nio.charset.Charset
    • Charset.forName() 方法根据字符集的名称返回一个 Charset 对象。该方法是一个工厂方法,它隐藏了字符集对象的实际创建过程。
  • java.sql.DriverManager
    • 在JDBC API中,DriverManager.getConnection() 方法根据数据库URL、用户名和密码返回一个 Connection 对象。这是工厂方法模式的一个应用,它封装了数据库连接对象的创建细节。
  • java.lang.NumberFormat
    • NumberFormat 类提供了多个工厂方法(如 getNumberInstance(), getCurrencyInstance())来获取不同格式化风格的 NumberFormat 对象。
在Spring中的应用:
  • Spring的BeanFactory
    • BeanFactory 是Spring框架的核心接口,它提供了高级的配置机制来管理任何类型的对象。BeanFactory 作为一个对象工厂,它为依赖注入(DI)提供了支持,管理应用程序中定义的bean,并在需要时创建和返回bean实例。
  • ApplicationContext
    • ApplicationContextBeanFactory 的子接口,提供了更丰富的功能。它不仅用于加载Bean定义,还提供了国际化、事件传播、资源加载等其他功能。在Spring中,ApplicationContext 通常用作Bean工厂。
  • FactoryBean
    • 在Spring中,FactoryBean 接口用于定义一个Bean,它本身作为工厂来生产其他对象。这个接口允许实现类在Spring容器中定义复杂的初始化逻辑。
  • 静态工厂方法和实例工厂方法
    • Spring允许通过静态工厂方法或实例工厂方法来创建Bean。这在Spring的配置中通过 <bean> 元素的 factory-method 属性来实现。
  • ServiceLocatorFactoryBean
    • 这是一个特殊的 FactoryBean,用于定义服务定位器。它可以用来抽象对服务接口的访问,使得客户端代码不需要直接与服务实现类耦合。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

haoxin963

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值