ホームページ  >  記事  >  バックエンド開発  >  PHPファクトリーパターンのユースケースと分析

PHPファクトリーパターンのユースケースと分析

php中世界最好的语言
php中世界最好的语言オリジナル
2018-05-17 11:20:141347ブラウズ

今回は、PHP ファクトリーモードのユースケースと分析についてお届けします。以下は、実践的なケースです。見てみましょう。 ファクトリー デザイン パターンは、クリエイティブなデザイン パターンとして、オープンクローズの原則に従い、変更に対して閉じられ、拡張に対してオープンです。ファクトリー メソッド (Factory Method) パターンでは、メソッド パターンで「何か」を作成します。作成される「物」は製品であり、この製品とそれを作成するクラスの間には何の結合もありません。実際、この疎結合を維持するために、クライアントはファクトリを通じてリクエストを行います。リクエストされたプロダクトを作成します。ファクトリメソッドパターンを使用して、別の方法で考えることもできます。

まず、ファクトリーの仕事です。ファクトリ インターフェイスを作成しますFactory。php

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

start メソッドはプロダクトを返します。このメソッドは、プロダクトの生成操作を完了するために createProduct メソッドを呼び出します。 、createProduct の特定の実装をビルドし、Product インターフェイス実装の Product オブジェクトを返す必要があります。

たとえば、すべての製品には共通のメソッド getProperties() があり、対応する Product インターフェイスは次のとおりです

Product.php

start方法返回一个产品,该方法调用createProduct方法完成产生产品的操作.所以createProduct的具体实现要构建并返回一个按Product接口实现的产品对象.

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

Product.php

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

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

TextFactory.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();
 }
}

PhotoFactory.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();
 }
}

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

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

下面的是两个产品的实现

TextProduct.php

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

PhotoProduct.php

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

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

客户(Client)

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

Client.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();

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

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

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

调整产品

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

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

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

增加新产品和参数化请求

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

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

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

次に、テキスト ファクトリ TextFactory とイメージ ファクトリ phptoFactory の 2 つのファクトリを作成する必要があります🎜🎜🎜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 メソッドにはポリモーフィズムが導入されており、このメソッドは「Text」または「Image」を返すために使用されます。同じ getProperties() には複数の (ポリ) 異なるフォーム (モーフ) があります。これはポリモーフィズムです。この場合、フォームの 1 つは text を返し、もう 1 つは image を返します。🎜🎜プロパティの実装には必要なものを何でも入れることができ、ファクトリ メソッドの設計によってこのオブジェクトが作成され、クライアントに返されます。 🎜🎜以下の 2 つの製品です。🎜🎜🎜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();
🎜の実装です。これらの 2 つの製品は、Product インターフェイス getProperties() に抽象メソッドを実装しています。 code>, 🎜🎜🎜🎜Customer (Client) )🎜🎜🎜🎜実際、このようにして、製品を追加する場合、顧客が直接製品リクエストを行うことを望んでいません。将来的には、顧客はアプリを中断することなく、より多くの種類の製品を取得できます: 🎜🎜🎜Client.php🎜🎜rrreee🎜 Client.php を実行し、次の結果を取得します🎜<blockquote style="text- align: left;">🎜これが画像プロダクトです<br>ここがテキストプロダクトです🎜</blockquote>🎜🎜注: 🎜クライアントオブジェクトはプロダクトに直接リクエストを行うのではなく、ファクトリを通じてリクエストを行います。問題は、クライアントが製品機能を実装するのではなく、反映するのは製品実装に任せることです🎜🎜🎜プロダクトを調整します🎜🎜🎜デザインパターンの本当の価値は、動作速度を上げることではなく、スピードアップすることです開発。🎜🎜ニーズが変わった場合は、画像プロダクトを変更する必要があります。対応するプロダクト PhotoProduct の getProperties メソッドを変更するだけです🎜🎜 オブジェクトの変更は非常に簡単に見えますが、<code>getProperties() Product の メソッドは引き続き同じインターフェイスを維持し、ファクトリにプロパティ オブジェクトを返すように要求します🎜🎜🎜 新しい製品とパラメータ化されたリクエストを追加します🎜🎜🎜 問題は、さらに画像とテキストの説明を追加したい場合です。新しいエリアを追加するたびに、新しい特定のファクトリ クラスを追加する必要がありますか? これは、新しいエリアごとに新しいファクトリと製品を追加することを意味します。そこで、パラメトリック ファクトリ デザイン パターンを導入しました🎜🎜 パラメトリック ファクトリ デザインの主な違いの 1 つです。パターンと一般的なファクトリ設計パターンでは、クライアントにはリクエストのパラメータにファクトリと製品への参照が含まれます。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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。