【设计模式】工厂模式

创建型设计模式: 工厂模式 factory
简单工厂, 工厂方法, 抽象工厂

工厂模式

  1. 简单工厂
  2. 工厂方法
  3. 抽象工厂

简单工厂

上层逻辑将需要的实例类型给到工厂, 工厂根据需求返回对应的对象. 一般通过条件分支语句实现

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
// factory code
class Factory {
public function getProduct($type) {
$product = null;
switch($type) {
case 1:
$product = new ProductA();
break;
case 2:
$product = new ProductB();
break;
}
return $product;
}
}

// product code
interface Product
{
public function show();
}

class ProductA implements Product
{
public function show()
{
echo 'Show ProductA';
}
}

class ProductB implements Product
{
public function show()
{
echo 'Show ProductB';
}
}

// super code
$type = $_REQUEST['type'];
$factory = new Factory();
$product = $factory->getProduct($type);
$product->show();

工厂方法

摒弃简单工厂中的条件分支判断, 将对象的实例交给具体的工厂
将对象的创建延迟到子类中进行, 不对外暴露具体实例化了哪个类
一个具体工厂类只能生成一种具体的产品类的对象,不同的具体工厂生成不同的产品,而不是像简单工厂中那样,一个工厂类可以生成多种不同产品类的对象

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
// factory code
abstract class Factory {
static public function factoryMethod($type) {
$factory = null;
switch($type) {
case 1:
$factory = new FactoryA();
break;
case 2:
$factory = new FactoryB();
break;
}
return $factory;
}
abstract public function getProduct();
}

class FactoryA extends Factory {
public function getProduct()
{
return new ProductA();
}
}

class FactoryB extends Factory {
public function getProduct()
{
return new ProductB();
}
}

// product code
interface Product
{
public function show();
}

class ProductA implements Product
{
public function show()
{
echo 'Show ProductA';
}
}

class ProductB implements Product
{
public function show()
{
echo 'Show ProductB';
}
}

// super code
$factory = Factory::factoryMethod(2);
$product = $factory->getProduct();
$product->show();

抽象工厂

和工厂方法很类似, 但是一个工厂可以生成多个产品

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// factory code
abstract class Factory {
static public function factoryMethod($type) {
$factory = null;
switch($type) {
case 1:
$factory = new Factory1();
break;
case 2:
$factory = new Factory2();
break;
}
return $factory;
}
abstract public function getProductA();
abstract public function getProductB();
}

class Factory1 extends Factory {
public function getProductA()
{
return new ProductA1();
}

public function getProductB()
{
return new ProductB1();
}
}

class Factory2 extends Factory {
public function getProductA()
{
return new ProductA2();
}

public function getProductB()
{
return new ProductB2();
}
}

// product code
interface ProductA
{
public function showA();
}

interface ProductB
{
public function showB();
}

class ProductA1 implements ProductA
{
public function showA()
{
echo 'Show ProductA1';
}
}

class ProductA2 implements ProductA
{
public function showA()
{
echo 'Show ProductA2';
}
}

class ProductB1 implements ProductB
{
public function showB()
{
echo 'Show ProductB1';
}
}

class ProductB2 implements ProductB
{
public function showB()
{
echo 'Show ProductB2';
}
}

// super code
$factory = Factory::factoryMethod(2);
$productA = $factory->getProductA();
$productB = $factory->getProductB();
$productA->showA();
$productB->showB();

比较

  1. 简单工厂
    简单工厂方法中,包括一个“抽象产品类”(该类可以是接口Interface,也可以是实际的类Class),所有需要的产品类都是该“抽象产品类”的子类(如果是接口的话,那么就是说所有产品类都继承了该接口)。
    简单工厂一般只包含一个具体的工厂类,由该工厂类生成所有的产品类的对象。生成产品类的方法,其内部一般是类似于switch的结构,根据输入的标志,选择创建不同类型的对象。由于不知道创建的对象到底是哪个类的,所以方法的返回值的类型是“抽象产品类”。

  2. 工厂方法
    抽象工厂中,包括“抽象工厂类”和“抽象产品类”,同时包含不只一个工厂类。所有的工厂类都必须是“抽象工厂类”的子类,所有的产品都必须是“抽象产品类”的子类。
    和简单工厂比起来,工厂方法一般是从抽象工厂开始的。一般都是在抽象工厂类中提供一个静态方法,由该方法根据输入的标志,生成不同的具体工厂类,然后由具体的产品类生成具体的产品。注意,一个具体工厂类只能生成一种具体的产品类的对象,不同的具体工厂生成不同的产品,而不是像简单工厂中那样,一个工厂类可以生成多种不同产品类的对象。可以这么理解,在选择不同的具体工厂类的时候,就选择了生成的产品,相对于简单工厂,相当于将选择产品的动作提前了。
    因为不知道创建的具体工厂类到底是哪一个,所以生成具体工厂类的静态方法的返回值的类型是“抽象工厂类”。具体工厂类生成产品类的方法,返回值的类型也要求是“抽象产品类”(因为前端调用的时候,需要使用同样的代码来访问)。

  3. 抽象工厂
    抽象工厂和工厂方法很类似,区别如下:
    工厂方法模式:
    一个抽象产品类,可以派生出多个具体产品类。
    一个抽象工厂类,可以派生出多个具体工厂类。
    每个具体工厂类只能创建一个具体产品类的实例。
    抽象工厂模式:
    多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
    一个抽象工厂类,可以派生出多个具体工厂类。
    每个具体工厂类可以创建多个具体产品类的实例。
    区别:
    工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
    工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个

https://www.pudn.com/news/628f8480bf399b7f351f046f.html