工厂方法
工厂方法与普通的简单工厂不同,我们可以拥有多个工厂,而不是一个工厂。
那么,为什么要这样做呢?要理解这一点,我们必须从开放/封闭原则(OCP)入手。伯特兰-梅耶尔(Bertrand Meyer)在他的著作《面向对象的软件结构》(Object-oriented Software Construction)中提出了 "开放/封闭原则"(open/closed principle)这一术语。梅耶尔指出了以下几点:
“软件实体(类、模块、函数等)应该对扩展开放,但对修改关闭”
如果需要对软件实体进行扩展,则应在不修改其源代码的情况下进行。熟悉面向对象软件 SOLID(单一责任、开放封闭、Liskov 替代、接口隔离和依赖反转)原则的人可能已经听说过这一原则。通过工厂方法,您可以将某些类组合在一起,并通过针对一组类的单独工厂来处理它们。如果你想添加另一个组,只需添加另一个工厂即可。
那么,现在我们该怎么做呢?基本上,我们要为每个工厂创建一个接口(或一个抽象方法);然后在我们要创建的其他工厂中实现该接口。
因此,让我们克隆我们的简单工厂演示;我们要做的是将 NotifierFactory
变成一个接口。这样,我们就可以重建工厂,为电子通知(电子邮件或短信)创建一个工厂,然后再实现我们的接口,创建一个邮政快递通知工厂。
因此,我们首先在 NotifierFactory.php
文件中创建接口:
<?php
interface NotifierFactory
{
public static function getNotifier($notifier, $to);
}
现在让我们构建实现 NotifierFactory
接口的 ElectronicNotifierFactory
:
Unresolved include directive in modules/ROOT/pages/ch03/ch3-03.adoc - include::example$/Chapter 3/FactoryMethod/ElectronicNotifierFactory.php[]
我们现在可以重构我们的 index.php
以使用我们创建的新工厂:
Unresolved include directive in modules/ROOT/pages/ch03/ch3-03.adoc - include::example$/Chapter 3/FactoryMethod/index.php[]
现在给出与以前相同的输出:
This is a SMS to 07111111111.
This is a Email to test@example.com from Junade.
不过,这样做的好处是,我们现在可以添加一种新的通知程序,而根本不需要打开工厂,让我们为邮政通信添加一个新的通知程序:
Unresolved include directive in modules/ROOT/pages/ch03/ch3-03.adoc - include::example$/Chapter 3/FactoryMethod/Post.php[]
然后我们可以引入 CourierNotifierFactory
:
Unresolved include directive in modules/ROOT/pages/ch03/ch3-03.adoc - include::example$/Chapter 3/FactoryMethod/CourierNotifierFactory.php[]
最后,我们现在可以修改我们的 index.php
文件以包含这种新格式:
Unresolved include directive in modules/ROOT/pages/ch03/ch3-03.adoc - include::example$Chapter 3/FactoryMethod/index.php[]
index.php
文件现在产生以下结果:

在生产中,您通常会将通知程序放在不同的名称空间中,同时将工厂放在不同的名称空间中。