简单工厂模式又称为静态工厂方法模型,它属于类创建型模式,简单工厂并不属于23种设计模式,刚开始学习设计模式的同学,对简单工厂模式、工厂方法、抽象工厂中的工厂一知半解,其实白话点来说:这些模式一定会有一个工厂类,子类并不需要知道工厂细节,只需新建工厂创建产品即好。
假设你正在开发一款组装DIY台式电脑
的应用,最初版本只需要拼装一台台式电脑并计算出每台总部件价格即可,因此大部分代码都在DIY台式电脑
的类中。
// DiyComputer.php
// 鼠标
$mouse = new Mouse();
$mousePrice = $mouse->getPrice();
// 键盘
$keyboard = new Keyboard();
$keyboardPrice = $keyboard->getPrice();
// 显示器
$display = new Display();
$displayPrice = $display->getPrice();
....
// 计算组装所有部件价格
echo $mousePrice + $keyboardPrice + $displayPrice + ...;
过了一段时间,使用DIY台式电脑
的用户都觉得普通有线键盘不好用,需要换成无线键盘,这时你可能需要对每个DIY台式电脑
的类修改键盘类代码。
// DiyComputer.php
// 鼠标
$mouse = new Mouse();
$mousePrice = $mouse->getPrice();
// 键盘
// $keyboard = new Keyboard();
$keyboard = new WirelessKeyboard();
$keyboardPrice = $keyboard->getPrice();
// 显示器
$display = new Display();
$displayPrice = $display->getPrice();
....
// 计算组装所有部件价格
echo $mousePrice + $keyboardPrice + $displayPrice + ...;
更糟糕的是,如果以后这些DIY台式电脑
的用户需要换其它部件,很有可能需要再次对这些代码进行大幅度修改。
简单工厂方法模式解决频繁更换各个部件,无法预知对象确切类别及其依赖关系时,可以用简单工厂方法。
白话文:需求频繁变动,没有切确的功能,避免代码多次重复改,可以采用此方法。
建立一个产品基类。如 Product
产品基类。然后,确保所有部件实现产品基接口。例如,鼠标实现 产品 接口;所有部件都实现 键盘 接口,以此类推。
建立一个组装工厂,其中有 production
生产产品类方法,production
方法通过传入的值, Switch
选择创建对象。客户端知道工厂提供 所有的部件创建方法,但是并不关心其具体实现方式
1个工厂 1个 interface 或者 abstract 产品基类 多个实现 interface 或者继承 abstract 的具体产品
//Factory.php
class Factory
{
/**
* 生产工厂
* @param string $product
* @return Product
*/
static public function production(string $product): Product
{
switch ($product) {
case 'mouse':
$result = new Mouse();
break;
case 'keyboard':
$result = new Keyboard();
break;
case 'display':
$result = new Display();
break;
default:
throw new \InvalidArgumentException('没有此部件');
}
return $result;
}
}
// Product.php
interface Product
{
public function getPrice();
}
// Mouse.php
class Mouse implements Product
{
public function getPrice(): float
{
return 499.99;
}
}
// Keyboard.php
class Keyboard implements Product
{
public function getPrice(): float
{
return 149.99;
}
}
//Display.php
class Display implements Product
{
public function getPrice(): float
{
return 1499.99;
}
}
DiyComputer.php
// 生成鼠标
$mouse = Factory::production('mouse');
$mousePrice = $mouse->getPrice();
// 生成键盘
$keyboard = Factory::production('keyboard');
$keyboardPrice = $keyboard->getPrice();
// 生成显示器
$display = Factory::production('display');
$displayPrice = $display->getPrice();
....
// 计算组装所有部件价格
echo $mousePrice + $keyboardPrice + $displayPrice + ...;