工厂方法设计模式 php 实现

为什么要用

保持代码之间的松耦合

何时使用

当一个类要创建的对象数目不确定的时候。
简单的说就是你去外边吃饭,直接告诉饭店去做具体的饭,最后你会吃上你点的菜(松耦合)。
当然,如果你想自己做,可以在家里自己做菜自己吃。但是你想吃你不会做的菜的时候只能自己现学(耦合性太强)。

怎么使用

工厂方法设计模式的主要参与者为:

  • 客户端
  • 工厂
  • 产品

工厂类

creator 接口

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
/**
* 工厂
*/
abstract class AFactory
{
trueprotected abstract function makeFood();

truepublic function order()
{
truetrue$food = $this->makeFood();
truetruereturn $food;
true}
}

/**
* 披萨
*/
class pizzaFactory extends AFactory
{
trueprotected function makeFood()
{
truetrue$pizza = new pizzaProduct();
truetruereturn $pizza->getFood();
true}
}

/**
* 水饺
*/
class dumplingFactory extends AFactory
{
trueprotected function makeFood()
{
truetrue$dumpling = new dumplingProduct();
truetruereturn $dumpling->getFood();
true}
}

产品类

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
/**
* 产品
*/
interface Product
{
truepublic function getFood();
}

class pizzaProduct implements Product
{
trueprivate $product;

truepublic function getFood()
{
truetrue$this->product = 'pizza';
truetruereturn $this->product;
true}
}

class dumplingProduct implements Product
{
trueprivate $product;

truepublic function getFood()
{
truetrue$this->product = 'dumpling';
truetruereturn $this->product;
true}
}

客户端调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class client
{
trueprivate $pizza;
trueprivate $dumpling;

truepublic function __construct()
{
truetrue$this->pizza = new pizzaFactory();
truetrueecho $this->pizza->order().PHP_EOL;
truetrue$this->dumpling = new dumplingFactory();
truetrueecho $this->dumpling->order().PHP_EOL;
true}
}
$worker = new client();

输出

pizza
dumpling

这里 client 没有参与具体的产品实现,只是请求了一下相应的工厂,之后如果产品产生了修改,client 是不用做改变的。

产品产生修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// dumpling 变成了  big dumpling , 不要告诉我是包子
class dumplingProduct implements Product
{
trueprivate $product;

truepublic function getFood()
{
truetrue$this->product = 'big dumpling';
truetruereturn $this->product;
true}
}
class pizzaProduct implements Product
{
trueprivate $product;

truepublic function getFood()
{
truetrue$this->product = 'new tasting pizza';
truetruereturn $this->product;
true}
}

输出:
new tasting pizza
big dumpling

新增产品与参数化实现

在上面的设计中,如果新增一个三明治,那么必须增加一个三明治工厂和三明治产品。
那么如果直接通过参数指定一个产品给工厂呢?

改进的新工厂

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 食物工厂
*/
class foodFactory extends AFactory
{
private $food;
protected function makeFood(Product $product)
{
$this->food = $product;
return $this->food->getFood();
}
}

增加的新产品

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 新产品
*/
class sandwichProduct implements Product
{
private $product;
public function getFood()
{
$this->product = 'sandwich';
return $this->product;
}
}

带参数的客户端

1
2
3
4
5
6
7
8
9
10
11
12
class client
{
private $food;

truepublic function __construct()
{
$this->food = new foodFactory();
echo $this->food->order(new sandwichProduct()).PHP_EOL;
echo $this->food->order(new pizzaProduct()).PHP_EOL;
true}
}
$worker = new client();

下次再想增加新产品就不用再添加一个新的工厂了~
神不神奇,惊不惊喜 ( ̄▽ ̄)~*