>  기사  >  백엔드 개발  >  PHP 팩토리 패턴 사용 사례 및 분석

PHP 팩토리 패턴 사용 사례 및 분석

php中世界最好的语言
php中世界最好的语言원래의
2018-05-17 11:20:141340검색

이번에는 PHP 팩토리 모드 사용 사례 및 분석을 가져오겠습니다. PHP 팩토리 모드 사용 사례 및 분석의 주의 사항은 다음과 같습니다.

팩토리 디자인 패턴(Factory Design Pattern)은 창의적 디자인 패턴으로서 개방형(open-closed), 수정형(closed), 확장형(open)을 따릅니다. 생성될 "사물"은 제품이며, 이 제품과 이를 생성하는 클래스 사이에는 바인딩이 없습니다. 실제로 이러한 느슨한 결합을 유지하기 위해 클라이언트는 팩토리를 통해 요청합니다. 요청한 제품을 다른 방법으로 생각해 볼 수도 있습니다. 요청자는 제품을 구체적으로 생성하지 않고 요청만 발행합니다. 팩토리 인터페이스 만들기

Factory.php

<?php
abstract class Factory
{
 //抽象的创建对象的方法
 protected abstract function createProduct();
 //该方法调用createProduct方法返回一个产品对象.
 public function start()
 {
   return $this->createProduct();
 }
}
start 메소드는 제품 생성 작업을 완료하기 위해 createProduct 메소드를 호출하는 제품을 반환합니다. , createProduct의 특정 구현을 빌드하고 제품 인터페이스 구현 Product 객체를 반환해야 합니다.

예를 들어 모든 제품에는 공통 메소드 getProperties()가 있으며 다음은 해당 제품 인터페이스

입니다. Product.php

<?php
//产品接口
interface Product
{
 public function getProperties();
}

다음으로 두 개의 팩토리, 즉 텍스트 팩토리 TextFactory와 이미지 팩토리 phptoFactorystart方法返回一个产品,该方法调用createProduct方法完成产生产品的操作.所以createProduct的具体实现要构建并返回一个按Product接口实现的产品对象.

比如产品都有一个共同的方法getProperties(), 以下是对应Product接口

Product.php

<?php
include_once(&#39;Factory.php&#39;);
include_once(&#39;TextProduct.php&#39;);
class TextFactory extends Factory
{
 protected function createProduct()
 {
  $product = new TextProduct();
  return $product->getProperties();
 }
}

接着, 我们要建立两个工厂,文本工厂TextFactory和图像工厂phptoFactory

TextFactory.php

<?php
include_once(&#39;Factory.php&#39;);
include_once(&#39;PhotoProduct.php&#39;);
class PhotoFactory extends Factory
{
 protected function createProduct()
 {
  $product = new PhotoProduct();
  return $product->getProperties();
 }
}

PhotoFactory.php

<?php
include_once(&#39;Product.php&#39;);
class TextProduct implements Product
{
 public function getProperties()
 {
  return "这里是文本产品";
 }
}

可以看到,在工厂方法的实现中, getProperties方法引入了多态(polymorphism), 将用这个方法返回"文本"或"图像". 同一个getProperties()有多个(poly)不同的形态(morphs), 这就是多态.在这种情况下, 其中一种形式返回文本, 而另一种返回图像.

可以在properties这个实现中放入你想要的任何东西,工厂方法设计将会创建这个对象, 并把他返回给Client使用.

下面的是两个产品的实现

TextProduct.php

<?php
include_once(&#39;Product.php&#39;);
class PhotoProduct implements Product
{
 //这是产品具有的方法
 public function getProperties()
 {
  return "这里是图像产品";
 }
}

PhotoProduct.php

<?php
include_once(&#39;PhotoFactory.php&#39;);
include_once(&#39;TextFactory.php&#39;);
class Client
{
 public function construct()
 {
  $this->somePhotoObject = new PhotoFactory();
  echo $this->somePhotoObject->start() . &#39;<br />&#39;;
  $this->someTextObject = new TextFactory();
  echo $this->someTextObject->start() . &#39;<br />&#39;;
 }
}
$worker = new Client();

这两个产品实现了Product接口中的抽象方法getProperties(),

客户(Client)

我们并不希望客户直接做出产品请求.实际上, 我们希望客户通过Factory工厂接口做出请求.这样一来,如果以后我们增加了产品或者工厂, 客户可以做同样的请求来得到更多类型的产品 , 而不会破坏这个应用:

Client.php

<?php
abstract class Factory
{
 //抽象的创建对象的方法
 protected abstract function createProduct(Product $product);
 //该方法由factoryMethod方法返回一个产品对象.
 public function start($product)
 {
   return $this->createProduct($product);
 }
}

运行Client.php, 得到下面的结果

这里是图像产品
这里是文本产品

注意: Client对象并没有向产品直接做出请求, 而是通过工厂来请求. 重要的是, 客户并不实现产品特性, 而留给产品实现来体现.

调整产品

设计模式的真正价值并不是提高操作的速度, 而是加快开发的速度.

如果现在需求变化了, 需要对图像产品做出修改, 只需要修改相应的产品PhotoProduct的getProperties方法即可

对象的改变看起来很简单 不过Product的getProperties()方法仍保持相同的接口,请求工厂返回一个属性对象

增加新产品和参数化请求

问题来了,如果要增加更多的图像和文本说明, 有没有必要每次增加一个新的区域就增加一个新的具体的工厂类?这意味着要为每个新区域增加一个新工厂和产品.于是,我们引进了参数化工厂设计模式

参数化工厂设计模式和一般的工厂设计模式的主要区别之一是客户包含工厂和产品的引用. 在参数化请求中, Client类必须指定产品, 而不是产品工厂. createProduct()

🎜TextFactory.php🎜🎜
<?php
include_once(&#39;Factory.php&#39;);
include_once(&#39;Product.php&#39;);
class CommonFactory extends Factory
{
 protected function createProduct(Product $product)
 {
  return $product->getProperties();
 }
}
🎜🎜PhotoFactory.php🎜🎜
<?php
//产品接口
interface Product
{
 public function getProperties();
}
🎜보시다시피 구현에서 생성해야 합니다. 팩토리 메소드의 getProperties 메소드는 다형성을 도입하며 이 메소드는 "텍스트" 또는 "이미지"를 반환하는 데 사용됩니다. 동일한 getProperties()에는 여러(폴리) 다른 형태(모프)가 있습니다. 이는 다형성입니다. 양식 중 하나는 텍스트를 반환하고 다른 하나는 이미지를 반환합니다.🎜🎜속성 구현에 원하는 것을 넣을 수 있으며 팩토리 메서드 설계는 이 객체를 생성하여 클라이언트에 반환합니다. 🎜🎜다음은 두 가지 제품입니다. 🎜🎜🎜TextProduct.php🎜🎜
<?php
include_once(&#39;Product.php&#39;);
class PenProduct implements Product
{
 public function getProperties()
 {
  return "钢笔产品";
 }
}
🎜🎜PhotoProduct.php🎜🎜
<?php
include_once(&#39;CommonFactory.php&#39;);
include_once(&#39;PenProduct.php&#39;);
class Client
{
 public function construct()
 {
  $commonFactory = new CommonFactory();
  echo $commonFactory->start(new PenProduct());
 }
}
$worker = new Client();
🎜 구현이 두 제품은 제품 인터페이스 getProperties()에서 추상 메소드를 구현합니다. code>, 🎜🎜🎜🎜고객(클라이언트) )🎜🎜🎜🎜저희는 고객이 직접 제품을 요청하는 것을 원하지 않습니다. 사실 이런 방식으로 제품을 추가하면 Factory 인터페이스를 통해 요청하기를 원합니다. 또는 향후 공장에서 고객은 앱을 중단하지 않고도 더 많은 유형의 제품을 얻을 수 있습니다. 🎜🎜🎜Client.php🎜🎜rrreee🎜Client.php를 실행하면 다음 결과를 얻을 수 있습니다🎜<blockquote style="text- align: left;">🎜여기에 이미지 제품이 있습니다<br>여기에 텍스트 제품이 있습니다🎜</blockquote>🎜🎜참고: 🎜클라이언트 개체는 제품에 직접 요청하지 않고 공장을 통해 요청합니다. 중요한 문제는 클라이언트가 제품의 기능을 구현하는 것이 아니라, 제품 구현에 반영하도록 맡기는 것입니다.🎜🎜🎜제품을 조정하세요🎜🎜🎜디자인 패턴의 진정한 가치는 작업 속도를 높이는 것이 아니라 속도를 높이는 것입니다. development.🎜🎜이제 요구사항이 바뀌면 이미지 상품을 수정해야 하는데, 해당 상품 PhotoProduct의 getProperties 메소드만 수정하면 됩니다.🎜🎜오브젝트 변경은 아주 간단해 보이지만 <code>getProperties() Product의 메소드는 여전히 동일한 인터페이스를 유지하며 공장에 속성 객체를 반환하도록 요청합니다🎜🎜🎜 새로운 제품 및 매개변수화된 요청 추가🎜🎜🎜질문은 더 많은 이미지와 텍스트 설명을 추가하려는 경우입니다. 새로운 영역을 추가할 때마다 새로운 특정 공장 클래스를 추가해야 합니까? 이는 각각의 새로운 영역에 새로운 공장과 제품이 추가됨을 의미합니다. 그래서 우리는 파라메트릭 공장 설계 패턴을 도입했습니다.🎜🎜파라메트릭 공장 설계의 주요 차이점 중 하나는 다음과 같습니다. 패턴과 일반적인 팩토리 디자인 패턴은 클라이언트가 팩토리 및 제품에 대한 참조를 포함한다는 것입니다. 요청에서 클라이언트 클래스는 createProduct() 작업은 클라이언트가 전달한 제품이므로 클라이언트가 원하는 특정 제품을 지정해야 합니다. 그러나 요청은 여전히 ​​팩토리 인터페이스를 통해 이루어집니다. 따라서 고객이 제품 참조를 포함하고 있습니다. 여전히 공장을 통해 제품과 분리되어 있습니다.🎜<p style="text-align: left;"><span style="font-size: medium"><strong>一个工厂多个产品(参数化工厂方法)</strong></span></p> <p style="text-align: left;">对于大多数请求, 参数化工厂方法更为简单, 因为客户只需要处理一个具体工厂.工厂方法操作有一个参数,指示需要创建的产品.而在原来的设计中, 每个产品都有自己的工厂, 不需要另个传递参数; 产品实现依赖于各个产品特定的工厂.</p> <p style="text-align: left;"><strong>新工厂接口</strong></p> <p style="text-align: left;"><strong>Factory.php</strong></p><pre class="brush:php;toolbar:false;">&lt;?php abstract class Factory { //抽象的创建对象的方法 protected abstract function createProduct(Product $product); //该方法由factoryMethod方法返回一个产品对象. public function start($product) { return $this-&gt;createProduct($product); } }</pre><p style="text-align: left;">在这个新的Factory接口中可以看到, <code>create()start()都需要一个参数,指定一个Product对象, 而不是Product接口的一个特定实现, 所以可以接受任何Product的具体实例.

工厂具体实现

具体的创建者类CommonFactory实现了createProduct(),如下

CommonFactory.php

<?php
include_once(&#39;Factory.php&#39;);
include_once(&#39;Product.php&#39;);
class CommonFactory extends Factory
{
 protected function createProduct(Product $product)
 {
  return $product->getProperties();
 }
}

这个类调用Product的方法getProperties将产品返回给客户.

新产品

具体产品的变化并不会改变原来的Product接口,还是原来的代码

<?php
//产品接口
interface Product
{
 public function getProperties();
}

例如, 现在有一个钢笔产品PenProduct

PenProduct.php

<?php
include_once(&#39;Product.php&#39;);
class PenProduct implements Product
{
 public function getProperties()
 {
  return "钢笔产品";
 }
}

客户Clent(有参数)

<?php
include_once(&#39;CommonFactory.php&#39;);
include_once(&#39;PenProduct.php&#39;);
class Client
{
 public function construct()
 {
  $commonFactory = new CommonFactory();
  echo $commonFactory->start(new PenProduct());
 }
}
$worker = new Client();

运行后输出

钢笔产品

以后如果开发出了新的产品, 只需要创建对应的产品类, 然后客户指定想要的新产品 , 即可返回客户需要的产品.

总结:

产品改变: 接口不变

使用设计模式的一大好处就是可以很容易地对类做出改变, 而不会破坏更大的程序. 之所以能够容易地做出改变, 秘诀在于保持接口不变, 而只改变内容.

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

PHP单一职责原则(SRP)使用案例解析

PHP实现红包金额拆分算法案例详解

위 내용은 PHP 팩토리 패턴 사용 사례 및 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.