工厂方法设计模式
2017-11-21 本文已影响12人
wudanyang
什么是工厂方法设计模式
工厂方法设计模式就是要创建一个产品,但是这个产品和创建他的类之间不存在绑定。
类型: 创建性设计模式
为什么要用
解决代码间的耦合问题
何时使用
当一个类要创建的对象数目不确定的时候。
简单的说就是你去外边吃饭,直接告诉饭店去做具体的饭,最后你会吃上你点的菜(松耦合)。
当然,如果你想自己做,可以在家里自己做菜自己吃。但是你想吃你不会做的菜的时候只能自己现学(耦合性太强)。
怎么使用
工厂方法设计模式的主要参与者为:
- 客户端
- 工厂
-
产品
类图:
工厂方法模式
工厂类
creator
接口
/**
* 工厂
*/
abstract class AFactory
{
protected abstract function makeFood();
public function order()
{
$food = $this->makeFood();
return $food;
}
}
/**
* 披萨
*/
class pizzaFactory extends AFactory
{
protected function makeFood()
{
$pizza = new pizzaProduct();
return $pizza->getFood();
}
}
/**
* 水饺
*/
class dumplingFactory extends AFactory
{
protected function makeFood()
{
$dumpling = new dumplingProduct();
return $dumpling->getFood();
}
}
产品类
/**
* 产品
*/
interface Product
{
public function getFood();
}
class pizzaProduct implements Product
{
private $product;
public function getFood()
{
$this->product = 'pizza';
return $this->product;
}
}
class dumplingProduct implements Product
{
private $product;
public function getFood()
{
$this->product = 'dumpling';
return $this->product;
}
}
客户端调用
class client
{
private $pizza;
private $dumpling;
public function __construct()
{
$this->pizza = new pizzaFactory();
echo $this->pizza->order().PHP_EOL;
$this->dumpling = new dumplingFactory();
echo $this->dumpling->order().PHP_EOL;
}
}
$worker = new client();
输出
pizza
dumpling
这里 client 没有参与具体的产品实现,只是请求了一下相应的工厂,之后如果产品产生了修改,client 是不用做改变的。
产品产生修改
// dumpling 变成了 big dumpling , 不要告诉我是包子
class dumplingProduct implements Product
{
private $product;
public function getFood()
{
$this->product = 'big dumpling';
return $this->product;
}
}
class pizzaProduct implements Product
{
private $product;
public function getFood()
{
$this->product = 'new tasting pizza';
return $this->product;
}
}
输出:
new tasting pizza
big dumpling
新增产品与参数化实现
在上面的设计中,如果新增一个三明治,那么必须增加一个三明治工厂和三明治产品。
那么如果直接通过参数指定一个产品给工厂呢?
带参数的工厂方法
改进的新工厂
/**
* 食物工厂
*/
class foodFactory extends AFactory
{
private $food;
protected function makeFood(Product $product)
{
$this->food = $product;
return $this->food->getFood();
}
}
增加的新产品
/**
* 新产品
*/
class sandwichProduct implements Product
{
private $product;
public function getFood()
{
$this->product = 'sandwich';
return $this->product;
}
}
带参数的客户端
class client
{
private $food;
public function __construct()
{
$this->food = new foodFactory();
echo $this->food->order(new sandwichProduct()).PHP_EOL;
echo $this->food->order(new pizzaProduct()).PHP_EOL;
}
}
$worker = new client();
输出:
sandwich
new tasting pizza
下次再想增加新产品就不用再添加一个新的工厂了~
哎呦,是不是很惊喜 ( ̄▽ ̄)~*