PHP设计模式——简单工厂

  • 2019 年 11 月 6 日
  • 筆記

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

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

本系列文章是为刚接触软件设计模式的开发人员和发现难以理解软件设计模式的开发人员编写的。

Dragon 公司是中国最大的玩具制造商之一。 实际上,他们是玩具制造的先驱。 他们是在很少有玩具被商业生产的时候开始生产的。 因此,他们占领了市场并成为玩具生产行业的领导者。这家玩具工厂,我们用代码来表示,把工厂表示成一个类ToysFactory

他们生产玩具的方式,我们用 produceToy()函数来表示,其代码表示如下:

class ToysFactory  {          public function produceToy($toyName)          {              $toy = null;              if ('car'==$toyName) {//生产汽车                  $toy = new Car();              } else if ('helicopter'==$toyName) {//生产直升机                  $toy = new Helicopter();              }              $toy->prepare();              $toy->package();              $toy->label();              return $toy;          }  }

最初,他们只生产玩具“汽车”和“直升机”。 对于这个简单的任务,该功能运行良好,每个人都很高兴。 但是不久之后,设计团队推出了一款很酷的新玩具“跳蛙(Jumping Frog)”。“跳蛙”看起来很酷,他们知道它的销售会真的很好,是时候添加新的生产玩具的方式,所以要更改productToy()函数了:

class ToysFactory  {        public function produceToy($toyName)      {              $toy = null;              if ('car'==$toyName) {//生产汽车                  $toy = new Car();              } else if ('helicopter'==$toyName) {//生产直升机                  $toy = new Helicopter();              } else if ('jumpingFrog'==$toyName) {//生产跳蛙                  $toy = new JumpingFrog();              }              $toy->prepare();              $toy->package();              $toy->label();              return $toy;      }  }

随着业务的增长,越来越多的玩具投入生产,首席执行官对公司的财务增长感到非常满意。 但是,在开发团队的办公室里,噩梦才刚刚开始。开发人员的任务是通过引入每个新玩具来修改ProduceToy()函数。它违反了打开/关闭原则。打开/关闭原则指的是“应打开软件实体(类(class),模块(modules),功能(functions)等)进行扩展,而关闭以进行修改”。每有新的玩具出现,都需要去更改produceToy()函数。

现在是重构的时候了。 让我们看看这些的情况。 ProduceToy()函数的真正问题是什么? 具体的类在ToysFactory类中实例化,并弄糟了produceToy()函数。 ToysFactory类与玩具的具体类联系在一起。 这就是问题所在。

首先,让我们创建一个类来封装实现玩具的具体类实例:

class SimpleFactory  {        public function createToy($toyName)      {          $toy = null;          if ('car'==$toyName) {              $toy = new Car();          } else if ('helicopter'==$toyName) {              $toy = new Helicopter();          }          return $toy;      }    }

其次,我们将使用SimpleFactory来创建一个全新的ToysFactory类:

class ToysFactory  {        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;      }    }

用了我们全新的类SimpleFactory,一切就变得更加简洁。 引入新玩具时,开发人员不再需要接触SimpleFactory,他们只使用SimpleFactory来生产新玩具,而不是使用以前的混乱代码。

这就是简单工厂模式。 它本身并不是真正的设计模式,但是它是一种有用的技术,可以应用于你自己的需求。 使用Simple Factory,可以封装具体的类实例。 它实现了将客户端代码与创建对象的代码分离。