Skip to content

Commit 8ca4879

Browse files
author
chenchangqin
committed
develop#工厂方法模式
1 parent 0fc03b0 commit 8ca4879

File tree

11 files changed

+295
-1
lines changed

11 files changed

+295
-1
lines changed

DesignerPatterns/AbstractFactory/Readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88

99
这种机制让替换平台变得简单,因为抽象工厂的具体实现类只有在实例化的时候才出现,如果要替换的话只需要在实例化的时候指定具体实现类即可。
1010
## 4、UML类图
11-
![Factory-UML.png](/static/images/Factory-UML.png)
11+
![Factory-UML.png](/static/images/Abstract-Factory-UML.png)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: chenchangqin
5+
* Date: 2018/12/19
6+
* Time: 16:44
7+
*/
8+
9+
namespace DesignerPatterns\FactoryMethod;
10+
11+
/**
12+
* 工厂方法抽象类
13+
*/
14+
abstract class FactoryMethod
15+
{
16+
const CHEAP = 1;
17+
const FAST = 2;
18+
19+
/**
20+
* 子类必须实现该方法
21+
*
22+
* @param string $type a generic type
23+
*
24+
* @return VehicleInterface a new vehicle
25+
*/
26+
abstract protected function createVehicle($type);
27+
28+
/**
29+
* 创建新的车辆
30+
*
31+
* @param int $type
32+
*
33+
* @return VehicleInterface a new vehicle
34+
*/
35+
public function create($type)
36+
{
37+
$obj = $this->createVehicle($type);
38+
$obj->setColor("#f00");
39+
40+
return $obj;
41+
}
42+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: chenchangqin
5+
* Date: 2018/12/19
6+
* Time: 16:48
7+
*/
8+
9+
namespace DesignerPatterns\FactoryMethod;
10+
11+
/**
12+
* Ferrari(法拉利)
13+
*/
14+
class Ferrari implements VehicleInterface
15+
{
16+
/**
17+
* @var string
18+
*/
19+
protected $color;
20+
21+
/**
22+
* @param string $rgb
23+
*/
24+
public function setColor($rgb)
25+
{
26+
$this->color = $rgb;
27+
}
28+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: chenchangqin
5+
* Date: 2018/12/19
6+
* Time: 16:45
7+
*/
8+
9+
namespace DesignerPatterns\FactoryMethod;
10+
11+
/**
12+
* GermanFactory是德国的造车厂
13+
*/
14+
class GermanFactory extends FactoryMethod
15+
{
16+
/**
17+
* {@inheritdoc}
18+
*/
19+
protected function createVehicle($type)
20+
{
21+
switch ($type) {
22+
case parent::CHEAP:
23+
return new Lamborghini();
24+
break;
25+
case parent::FAST:
26+
$obj = new Porsche();
27+
//因为我们已经知道是什么对象所以可以调用具体方法
28+
$obj->addTuningAMG();
29+
30+
return $obj;
31+
break;
32+
default:
33+
throw new \InvalidArgumentException("$type is not a valid vehicle");
34+
}
35+
}
36+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: chenchangqin
5+
* Date: 2018/12/19
6+
* Time: 16:44
7+
*/
8+
9+
namespace DesignerPatterns\FactoryMethod;
10+
11+
/**
12+
* ItalianFactory是意大利的造车厂
13+
*/
14+
class ItalianFactory extends FactoryMethod
15+
{
16+
/**
17+
* {@inheritdoc}
18+
*/
19+
protected function createVehicle($type)
20+
{
21+
switch ($type) {
22+
case parent::CHEAP:
23+
return new Lamborghini();
24+
break;
25+
case parent::FAST:
26+
return new Ferrari();
27+
break;
28+
default:
29+
throw new \InvalidArgumentException("$type is not a valid vehicle");
30+
}
31+
}
32+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: chenchangqin
5+
* Date: 2018/12/19
6+
* Time: 16:46
7+
*/
8+
9+
namespace DesignerPatterns\FactoryMethod;
10+
11+
/**
12+
* Porsche(保时捷)
13+
*/
14+
class Lamborghini implements VehicleInterface
15+
{
16+
/**
17+
* @var string
18+
*/
19+
protected $color;
20+
21+
/**
22+
* 设置自行车的颜色
23+
*
24+
* @param string $rgb
25+
*/
26+
public function setColor($rgb)
27+
{
28+
$this->color = $rgb;
29+
}
30+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: chenchangqin
5+
* Date: 2018/12/19
6+
* Time: 16:46
7+
*/
8+
9+
namespace DesignerPatterns\FactoryMethod;
10+
/**
11+
* Porsche(保时捷)
12+
*/
13+
14+
class Porsche implements VehicleInterface
15+
{
16+
/**
17+
* @var string
18+
*/
19+
protected $color;
20+
21+
/**
22+
* @param string $rgb
23+
*/
24+
public function setColor($rgb)
25+
{
26+
$this->color = $rgb;
27+
}
28+
29+
/**
30+
* 尽管只有奔驰汽车挂有AMG品牌,这里我们提供一个空方法仅作代码示例
31+
*/
32+
public function addTuningAMG()
33+
{
34+
}
35+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# PHP 设计模式系列 —— 工厂方法模式(Factory Method)
2+
## 1、模式定义
3+
定义一个创建对象的接口,但是让子类去实例化具体类。工厂方法模式让类的实例化延迟到子类中。
4+
5+
## 2、问题引出
6+
框架需要为多个应用提供标准化的架构模型,同时也要允许独立应用定义自己的域对象并对其进行实例化。
7+
8+
## 3、解决办法
9+
工厂方法以模板方法的方式创建对象来解决上述问题。父类定义所有标准通用行为,然后将创建细节放到子类中实现并输出给客户端。
10+
11+
人们通常使用工厂模式作为创建对象的标准方式,但是在这些情况下不必使用工厂方法:实例化的类永远不会改变;或者实例化发生在子类可以轻易覆盖的操作中(比如初始化)。
12+
13+
## 4、UML类图
14+
![Factory-Method-UML.png](/static/images/Factory-Method-UML.png)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: chenchangqin
5+
* Date: 2018/12/19
6+
* Time: 16:46
7+
*/
8+
9+
namespace DesignerPatterns\FactoryMethod;
10+
11+
/**
12+
* VehicleInterface是车辆接口
13+
*/
14+
interface VehicleInterface
15+
{
16+
/**
17+
* 设置车的颜色
18+
*
19+
* @param string $rgb
20+
*/
21+
public function setColor($rgb);
22+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: chenchangqin
5+
* Date: 2018/12/19
6+
* Time: 16:49
7+
*/
8+
9+
namespace Tests\FactoryMethodTest;
10+
11+
use DesignerPatterns\FactoryMethod\FactoryMethod;
12+
use DesignerPatterns\FactoryMethod\GermanFactory;
13+
use DesignerPatterns\FactoryMethod\ItalianFactory;
14+
15+
class FactoryMethodTest extends \PHPUnit_Framework_TestCase
16+
{
17+
protected $type = array(
18+
FactoryMethod::CHEAP,
19+
FactoryMethod::FAST
20+
);
21+
22+
public function getShop()
23+
{
24+
return array(
25+
array(new GermanFactory()),
26+
array(new ItalianFactory())
27+
);
28+
}
29+
30+
/**
31+
* @dataProvider getShop
32+
*/
33+
public function testCreation(FactoryMethod $shop)
34+
{
35+
// 该方法扮演客户端角色,我们不关心什么工厂,我们只知道可以可以用它来造车
36+
foreach ($this->type as $oneType) {
37+
$vehicle = $shop->create($oneType);
38+
/**
39+
* assertInstanceOf($expected, $actual[, $message = ''])
40+
* $actual 不是 $expected 的实例时报告错误,错误讯息由 $message 指定。
41+
*/
42+
$this->assertInstanceOf('DesignerPatterns\FactoryMethod\VehicleInterface', $vehicle);
43+
}
44+
}
45+
46+
/**
47+
* @dataProvider getShop
48+
* @expectedException \InvalidArgumentException
49+
* @expectedExceptionMessage spaceship is not a valid vehicle
50+
*/
51+
public function testUnknownType(FactoryMethod $shop)
52+
{
53+
$shop->create('spaceship');
54+
}
55+
}

0 commit comments

Comments
 (0)