设计模式笔记 - 工厂方法模式(Factory Method Pattern)

模式定义

工厂方法模式(Factory Method Pattern)又称为多态工厂(Polymorphic Factory)模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。


模式结构

工厂方法模式包含如下角色:

  • Factory:抽象工厂
  • ConcreteFactory:具体工厂
  • Product:抽象产品
  • ConcreteProduct:具体产品

img


模式实例

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
* 结合简单工厂模式中的例子,披萨店生意火爆,资金足以在外地开分店。但不同
* 地方所需求的披萨不同,比如纽约与芝加哥的风味完全不同。我们应该根据不同
* 地方的需求创建自己需要的生产工厂
*/
public class PizzaStore {
PizzaFactory pizzaFactory;

public PizzaStore(PizzaFactory pizzaFactory) {
this.pizzaFactory = pizzaFactory;
}

public void orderPizza(String item) {
Pizza pizza = pizzaFactory.createPizza(item);
pizza.display();
}
}

// Factory - 抽象工厂
public abstract class PizzaFactory {
public abstract Pizza createPizza(String item);
}

// ConcreteFactory - 具体工厂
// 纽约分店
public class NewYorkPizzaFactory extends PizzaFactory {
public Pizza createPizza(String item) {
if (item.equals("cheese")) {
return new NewYorkChessePizza();
} else {
return null;
}
}
}

// 芝加哥分店
public class ChiCagoPizzaFactory extends PizzaFactory {
public Pizza createPizza(String item) {
if (item.equals("cheese")) {
return new ChicagoChessePizza();
} else {
return null;
}
}
}

// Pizza实现等大同小异,不再一一复述
// 测试类
public class Test {
public static void main(String[] args) {
PizzaStore newYorkStore = new PizzaStore(new NewYorkPizzaFactory());
newYorkStore.orderPizza("new york");

PizzaStroe chicagoStore = new PizzaStore(new ChiCagoPizzaFactory());
chicagoStore.orderPizza("chicago");
}
}

模式分析

  • 工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了面向对象的多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责产品类被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
  • 在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需关心所需产品对应的工厂,无需关心创建细节,甚至无需知道具体产品类的类名。
  • 工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。

工厂方法模式的优点:

  • 基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部,符合“开闭原则”。
  • 在面对系统需要添加新的产品时,无须修改抽象工厂和抽象产品提供的接口,也无须修改现有的具体工厂和具体产品,而只需为新产品添加一个具体工厂和具体产品即可。

工厂方法模式的缺点:

  • 在添加新产品时,需要编写新的具体产品类以及相对应的具体工厂类,系统中类的数目将成对增加,在一定程度上增加了系统复杂度。


参考资料:

[1] https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/factory_method.html