前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP设计模式——工厂方法

PHP设计模式——工厂方法

作者头像
Lemon黄
发布2019-11-06 18:58:04
3370
发布2019-11-06 18:58:04
举报
文章被收录于专栏:Lemon黄Lemon黄

点击上方“Lemon黄”关注我哦,不定期原创文,定期好技术文推广分享

译者:Lemon黄 来源:https://www.startutorial.com/articles/view/understanding-design-patterns-factory-method

工厂方法:定义用于创建对象的接口,但是让实现该接口的类决定要实例化的类。 Factory方法允许类将实例化延迟到子类。

用了简单工厂(Simple Factory)的设计模式,开发人员现在可以在Dragon公司中享受他们的一天。尽管对玩具进行了详尽的讨论,但我们还没有真正研究过玩具类。 玩具类是具有功能prepare()package()label()的抽象类。

代码语言:javascript
复制
//玩具抽象类
abstract class Toy
{
    public $name  = '';
    public $price  = 0;
 
    public function prepare()
    {
        echo $this->name. ' is prepared';
    }
 
    public function package()
    {
        echo $this->name. ' is packaged';
    }
 
    public function label()
    {
        echo $this->name . ' is priced at '.$this->price;
    }
}

具体的汽车(Car)类,直升机(Helicopter )类从抽象父类(Toy)继承而来,这两个具体的类实现代码很简单,如下:

Car类:

代码语言:javascript
复制
class Car extends Toy
{
    public $name  = 'Car';
    public $price = 20;
}

Helicopter类:

代码语言:javascript
复制
class Helicopter extends Toy
{
    public $name  = 'Helicopter';
    public $price = 100;
}

回到Dragon 公司。首席执行官带着微笑笑着走进开发商办公室,但我们知道有坏消息要来。 首席执行官高兴地宣布,Dragon Inc.将在美国开设几家工厂。 他们将位于不同的州,前两个工厂将在纽约和加利福尼亚。 所有玩具将在当地生产并拥有自己的属性,这意味着对于同类型的玩具车,在纽约生产的玩具将是NyCar,在加利福尼亚生产的玩具将是CaCar。 简单工厂模式(Simple Factory)将使开发团队轻松完成此任务。 他们所需要做的就是创建一个特定于位置的SimpleFactory类和一个特定于位置的ToysFactory类。 简单工厂(SimpleFactory)模式简化了任务,使开发人员的工作变得容易。

例如,对于纽约,我们可以这样做:

代码语言:javascript
复制
//针对纽约 的简单工厂类
class NySimpleFactory
{
 
    public function createToy($toyName)
    {
        $toy = null;
        if ('car'==$toyName) {
            $toy = new NyCar();
        } else if ('helicopter'==$toyName) {
            $toy = new NyHelicopter();
        }
        return $toy;
    }
}

//针对纽约 的玩具工厂类
class NyToysFactory
{
    public $simpleFactory;
 
    public function __construct(SimpleFactory $simpleFactory)
    {
        $this->simpleFactory = $simpleFactory;
    }
 
    public function produceToy($toyName)
    {
        $toy = null;
        $toy = $this->simpleFactory->createToy($toyName);
        $toy->prepare();
        $toy->package();
        $toy->label();
        return $toy;
    }
}

开发人员可以迅速完成新代码,并将其移交给美国工厂。 两周后,由于纽约工厂出现生产问题,电话开始在开发人员办公室响起。 事实证明,NyToysFactory类已由远程分支的开发人员修改,因为那里的员工不想执行包装和标签工作。 他们通过删除label()package()函数来修改了produceToy()函数。

在这种情况下,简单工厂(SimpleFactory)模式似乎无法正常工作。 我们不希望美国的分支机构能够修改produceToy()函数。 produceToy()应该包含一组标准过程,并且分支机构仅应负责创建特定于位置的玩具。 如果他们可以创建一个抽象类怎么办? 他们创建的抽象类将具有一个具体的produceToy()方法,该方法将实现所有分支必须遵循的一组标准操作过程。 在produceToy()内部,它调用自己的抽象方法createToy()来获得玩具对象。 这种方式createToy()能够封装对象的创建,并且由于它是抽象的,因此将创建委托给其子类。

这听起来完全符合他们的要求:

代码语言:javascript
复制
abstract class ToysFactory
{
    public function produceToy($toyName)
    {
        $toy = null;
        $toy = $this->createToy($toyName);
        $toy->prepare();
        $toy->package();
        $toy->label();
        return $toy;
    }
 
    abstract public function createToy($toyName);
}

现在在纽约分支中,他们所需要做的就是在子类中实现createToy()方法:

代码语言:javascript
复制
class NyToysFactory extends ToysFactory
{
 
    public function createToy($toyName)
    {
        $toy = null;
        if ('car'==$toyName) {
            $toy = new NyCar();
        } else if ('helicopter'==$toyName) {
            $toy = new NyHelicopter();
        }
        return $toy;
    }
 
}

对于加利福尼亚的工厂,他们必须创建另一个子类CaToyFactory才能在本地生产玩具:

代码语言:javascript
复制
class CaToysFactory extends ToysFactory
{
    public function createToy($toyName)
    {
        $toy = null;
        if ('car'==$toyName) {
            $toy = new CaCar();
        } else if ('helicopter'==$toyName) {
            $toy = new CaHelicopter();
        }
        return $toy;
    }
}

在上面的代码中,ToysFactory类中的函数createToy()被称为工厂方法。 工厂方法模式定义用于创建对象的接口(createToy)。 但是它将实际的创建委托给子类(NyToysFactoryCaToyFactory)。 这样子类可以决定要创建的对象。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Lemon黄 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档