工厂方法又称为:虚拟构造函数、Virtual Constructor、Factory Method。定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类中。
接前一篇的 简单工厂 问题,简单工厂违背了开闭原则,每次修改或增添部件需要去工厂中修改工厂类,需要去修改工厂类的 Switch
具体逻辑。
也就是说我们每次修改都要去 简单工厂 的 Switch
增加或者删除,这即为不便,产品变多了,我们的工作也就越来越大了。
工厂方法则将问题交给具体客户端(DIY组装电脑
),需要什么部件实例化什么部件工厂类。让工厂的子类来确定实例化哪一个具体的产品类。
前面说到,产品变多,简单工厂 工作也就越来越大了,所以工厂方法模式对产品的每种类型新增一个工厂,以减少我们一个 简单工厂 的工作量,这样就将问题交给具体客户端。
1个 interface 或者 abstract 产品基类
多个实现 interface 或者继承 abstract 的具体产品类
1个 interface 或者 abstract 工厂基类
多个实现 interface 或者继承 abstract 的具体工厂类
具体工厂类和具体产品类一一对应
在具体工厂类中实例化具体的产品类
部件工厂基类,制定创建产品方法。
// Factory.php
interface Factory
{
public function production();
}
PHP
Copy
// KeyboardFactory.php
class KeyboardFactory implements Factory
{
public function production(): Product
{
return new KeyboardProduct();
}
}
// MouseFactory.php
class MouseFactory implements Factory
{
public function production(): Product
{
return new MouseProduct();
}
}
...
PHP
Copy
// Product.php
interface Product
{
public function getPrice();
}
PHP
Copy
// KeyboardProduct.php
class KeyboardProduct implements Product
{
public function getPrice(): float
{
return 149.99;
}
}
// MouseProduct.php
class MouseProduct implements Product
{
public function getPrice(): float
{
return 49.99;
}
}
PHP
Copy
// DiyComputer.php
// 键盘
$keyboardFactory = new KeyboardFactory();
$keyboard = $keyboardFactory->production();
$keyboardPrice = $keyboard->getPrice();
// 鼠标
$mouseFactory = new MouseFactory();
$mouse = $mouseFactory->production();
$mousePrice = $mouse->getPrice();
...
//总价格
echo $mousePrice + $keyboardPrice + ...;
PHP
Copy