工厂方法

工厂方法与普通的简单工厂不同,我们可以拥有多个工厂,而不是一个工厂。

那么,为什么要这样做呢?要理解这一点,我们必须从开放/封闭原则(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 文件现在产生以下结果:

image 2023 10 27 16 59 12 575

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