适用条件:
简单的说,所有的设计模式的目标都是为了以后的扩展. 当业务扩展时,尽可能少的修改原有代码. 我们知道,修改原有代码就有可能出错,会担责任的.
本模式适用于产品类型确定,但生产方式会发生变化的场景. 当业务变化时,可以通过增加具体工厂来生产新型号的产品.
限制条件:1.产品: 有多个不同类型的产品(对象), 如果只有一个产品,没必要使用此模式
2.产品: 每个类型的产品由不同的工厂生产时,会有差别, 但共同点居多. 即: 每个类型都是一个基类,每个产品都是某个基类的子类.
3.工厂: 有多个工厂,如果只有一个工厂, 也没必要使用此模式.
4.工厂: 每个工厂都可以生产每一种类型的产品,有差别,但共同点居多, 即:每个工厂都是工厂基类的子类
5.业务限制: 事先已经确定有多少种产品类型, 但工厂的个数不确定, 可能根据业务的发展随时增加.
6.业务限制:如果产品类型也随着业务的发展而变化 ,则此模式不适用.
注意:
看完具体实现后, 一定要看最后的示例.
具体实现:
class CAbstractFactory extends SController { public function index() { //工厂A,可以生成产品X和Y 的具体型号 X_A,Y_A $factory = new FactoryA(); $product = $factory->createProductX('X_A'); var_dump($product); // object(ProductX_A)#9 (1) { ["name":protected]=> string(3) "X_A" } $product = $factory->createProductY('Y_A'); var_dump($product); // object(ProductY_A)#10 (1) { ["name":protected]=> string(3) "Y_A" } //工厂B,可以生成产品X和Y的具体型号 X_B,Y_B $factory = new FactoryB(); $product = $factory->createProductX('X_B'); var_dump($product); // object(ProductX_B)#8 (1) { ["name":protected]=> string(3) "X_B" } $product = $factory->createProductY('Y_B'); var_dump($product); // object(ProductY_B)#10 (1) { ["name":protected]=> string(3) "Y_B" } } }
//下面三个类是固定的:产品X,产品Y,以及工厂基类 //定义X产品基类(抽象) abstract class ProductX { protected $name; public function __construct(string $name) { $this->name = $name; } } //另一种产品Y的基类(抽象) abstract class ProductY { protected $name; public function __construct($name) { $this->name = $name; } } //定义工厂基类(抽象),工厂可以生成产品X和Y abstract class AbstractFactory { abstract public function createProductX(string $name): ProductX; abstract public function createProductY(string $name): ProductY; }
//下面三个类是第A种实现,定义了A工厂和产品XY的A型号实现 //定义A厂生成的X产品 class ProductX_A extends ProductX { //A厂X产品的具体实现细节 } //定义A厂Y产品 class ProductY_A extends ProductY { //A厂Y产品的具体实现细节 } //定义工厂A,可以生成X产品和Y产品的具体型号:X_A,Y_A class FactoryA extends AbstractFactory { public function createProductX(string $name): ProductX { return new ProductX_A($name); } public function createProductY(string $name): ProductY { return new ProductY_A($name); } }
//现在三个类是第B种实现,定义了B工厂和产品XY的B型号实现 //定义B厂产品X class ProductX_B extends ProductX { //B厂X产品的具体实现细节 } //定义B厂Y产品 class ProductY_B extends ProductY { //B厂Y产品的具体实现细节 } //定义工厂B,可以生成产品X和Y的具体型号X_B,Y_B class FactoryB extends AbstractFactory { public function createProductX(string $name): ProductX { return new ProductX_B($name); } public function createProductY(string $name): ProductY { return new ProductY_B($name); } }
//如果有需要,还可以再定义 C工厂及产品XY的C型号实现,......
示例:
一个较复杂系统需要以下功能: 日志系统,调试信息系统,缓存系统.
当前硬件条件有限,打算用本地文件的方式来实现以上三个系统(即产品). 下一步目标是设立单独的数据库服务器来保存日志/调试信息/缓存,以供方便查询. 再下一步可能要使用MongoDB来保存数据,以便快速写入和方便查询.
产品类型有三种:日志,调试信息,缓存.
工厂最后也有三种: 文件方式, 数据库方式, MongoDB方式
每一个工厂可以创建一个版本的三种产品.