工厂方法模式(Factory Method Pattern)
概述
工厂方法模式(Factory Method Pattern)是一个对象创建型模式。它提供了一种将对象的创建逻辑抽象出来的方式,使得客户端代码不需要关心具体的对象创建细节,而是通过调用工厂方法来创建对象。这种模式有助于解耦对象的创建和使用,同时也提供了扩展和定制对象创建过程的灵活性。
在工厂方法模式中,通常会定义一个抽象工厂接口,其中包含一个用于创建产品对象的抽象方法。具体的产品类需要实现这个工厂接口,并提供自己的产品创建逻辑。客户端代码通过调用工厂方法来创建所需的产品对象,而无需关心具体的产品类。
定义
Define an interface for creating an object, but let subclasses decide which class to instantiate.
Factory Method lets a class defer instantiation to subclasses
定义一个用于创建对象的接口,让子类决定实例化哪一个类。 Factory Method使一个类的实例化延迟到其子类。
引用自《设计模式:可复用面向对象软件的基础》
说的更直白一点就是,定义一个工厂接口,将对象的实例化操作放到工厂的实现类中。
结构
这个例子中有饮品 Drink
和饮品工厂 DrinkFactory
,DrinkFactory
负责生产 Drink
。在现实生活中可口可乐(Coca
)和奶茶(MilkyTea
),不是由一家生产的,而是生产可口可乐的工厂生产可口可乐,Coco奶茶店可以生产奶茶。
当我们需要奶茶饮品的时候就需要用 CocoDrinkFactory
生产,当我们需要可口可乐的时候就需要用 CocaDrinkFactory
生产。
这个例子不太恰当,因为我们不会直接从可口可乐工厂购买可口可乐。但是我认为用这个例子来解释工厂方法模式是没有问题的。而且能够清晰的描述出工厂方法模式的使用场景。
实现
1 | public interface Drink { |
在开源框架中的应用
工厂方法模式在日志框架中的应用
工厂方法模式的一个典型应用场景是日志,准确的说是slf4j,这是一个日志的标准接口框架。其有着不同的实现,如logback, log4j。slf4j中的几个核心类
org.slf4j.Logger
:接口,是具体的日志输出的实现。不同的日志框架有不同的实现。org.slf4j.ILoggerFactory
:接口,日志工厂,用于创建Logger
。不同的日志框架有不同的实现,但是只是创建自己框架内的Logger
。org.slf4j.LoggerFactory
:类,用于获取org.slf4j.ILoggerFactory
org.slf4j.spi.SLF4JServiceProvider
:用于创建org.slf4j.ILoggerFactory
,不是本章的重点。在以后的日志框架分析文章中再做说明。java.util.ServiceLoader
:用于通过ClassLoader
发现org.slf4j.spi.SLF4JServiceProvider
,也不是本章的重点。
上图是logback
对slf4j
的实现。org.slf4j.LoggerFactory
通过 ServiceLoader
发现logback的对org.slf4j.spi.SLF4JServiceProvider
的实现ch.qos.logback.classic.spi.LogbackServiceProvider
。然后通过 SLF4JServiceProvider.getLoggerFactory()
获取org.slf4j.ILoggerFactory
。然后再调用LoggerFactory.getLogger()
创建org.slf4j.Logger
。
其他的日志框架,如log4j
对slf4j
的实现方式也是类似的。我们一般不能在一个系统中引入两套日志框架,否则会出现org.slf4j.LoggerFactory
不知道使用哪个ILoggerFactory
的实现的情况。
Spring框架中工厂方法模式的应用
在Spring中FactoryBean
就是使用了工厂方法模式的设计思想。Spring中的FactoryBean
接口允许用户自定义工厂bean,用于创建和管理对象实例。通过实现FactoryBean
接口,用户可以定义自己的工厂方法逻辑,实现对象的创建和初始化。
如 org.springframework.context.support.ConversionServiceFactoryBean
。
FactoryBean
中可以实现复杂的对象创建逻辑,用户也可以定义一些配置选项,从而更灵活地定制对象的创建和初始化过程。
何时使用
在下列情况下可以使用Factory Method模式:
- 当一个类不知道它所必须创建的对象的类的时候。
- 当一个类希望由它的子类来指定它所创建的对象的时候。
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
与简单工厂模式的区别
- 简单工厂模式(Simple Factory Pattern):在简单工厂模式中,有一个工厂类,该工厂类提供一个方法,根据传入的参数来创建并返回不同类型的对象实例。客户端只需要知道所需对象的参数,而不需要关心对象的创建过程。
- 工厂方法模式(Factory Method Pattern):工厂方法模式通过定义一个创建对象的接口,但是将实际创建工作推迟到子类中。这样每个子类都可以重写这个工厂方法以返回不同的对象类型,从而使得客户端可以通过子类的方式来创建对象。
简单工厂模式相对较简单,适用于创建对象的逻辑较为固定;而工厂方法模式更加灵活,允许不同的子类决定创建哪种对象,使得系统更容易扩展和维护。
总的来说,简单工厂模式将对象的创建逻辑集中在一个工厂类中,对客户端来说更加简单;而工厂方法模式将对象的创建逻辑分散到不同的子类中,更符合开闭原则,使得系统更加灵活和可扩展。
以上内容由ChatGPT生成
总结
工厂方法模式的优点是,我们知道要一个具体的对象,也知道这个对象的类。但是不用关心谁创建了它,创建的过程如何。
在上述日志框架中的应用可以看出,多个工厂其实是冲突的。在实际使用时我们只用一个即可。但是这并不是方法工厂模式的要求,方法工厂模式并没有要求多个工厂不能共存,需要结合实际的应用场景来灵活设计、灵活使用。切勿生搬硬套!
工厂方法模式(Factory Method Pattern)
http://jaune162.blog/design-pattern/factory-method-pattern.html