工厂方法模式(Factory Method Pattern),也被叫做工厂模式,虚拟构造器模式或多态工厂模式,属于类创建模式。在工厂方法模式中,父类定义了创建产品的公共接口, 具体的构造过程由子类完成,当有一个新的产品需要构建时,不需要去修改父类,仅仅增加一个子工厂类,即可完成,更加符合开闭原则。
设计模式-概述
结构
包含如下角色:
- Product 抽象产品
- ConcreteProduct 具体产品
- Factory 抽象工厂
- ConcreteFactory 具体工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| @startuml factory-method-1 !include ./common.iuml
Class(Product,"抽象产品") << abstract >> { +use() : void }
Class(ConcreteProduct,"具体产品") { +use() : void }
Class(Factory,"抽象工厂") << abstract >> { +factoryMethod() : Product }
Class(ConcreteFactory,"具体工厂") { +factoryMethod() : Product }
note as N1 return new ConcreteProduct(); end note
Product <|-- ConcreteProduct ConcreteProduct <-left- ConcreteFactory Factory <|-- ConcreteFactory ConcreteFactory -right- N1
@enduml
|
使用时序
1 2 3 4 5 6 7 8 9 10 11 12 13
| @startuml factory-method-2
actor iMain participant ConcreteFactory participant ConcreteProduct
activate iMain iMain -> ConcreteFactory : 1.0 factoryMethod():Product activate ConcreteFactory ConcreteFactory --> ConcreteProduct : 1.1 <<create>> iMain -> ConcreteProduct : 1.2 use()
@enduml
|
代码实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
public class Main { public static void main(String[] args) { Factory factory = new ConcreteFactory(); Product product = factory.factoryMethod(); product.use(); } }
abstract class Product { abstract public void use(); }
abstract class Factory { abstract Product factoryMethod(); }
class ConcreteProduct extends Product {
@Override public void use() { System.out.println("use ConcreteProduct"); } }
class ConcreteFactory extends Factory {
@Override Product factoryMethod() { return new ConcreteProduct(); } }
|
使用场景
是简单工厂模式的增强版本,既保持了简单工厂的优点,又克服了简单工厂类的缺点, 可以在不修改工厂类的情况下,产生新的Product, 仅需要继承抽象工厂类就好了。
- 一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;客户端需要知道创建具体产品的工厂类。
- 一个类通过其子类来指定创建哪个对象:在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
- 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。
应用
MyBatis中的SqlSessionFactory, 默认提供了两个实现类 org.apache.ibatis.session.SqlSessionManager
和 org.apache.ibatis.session.defaults.DefaultSqlSessionFactory
。