ホームページ  >  記事  >  バックエンド開発  >  PHPの簡易ファクトリパターンとファクトリパターンのまとめ

PHPの簡易ファクトリパターンとファクトリパターンのまとめ

小云云
小云云オリジナル
2018-01-25 17:01:441356ブラウズ

まずは簡単なファクトリパターンを見てみましょう。 コードは次のとおりです。

<?php
/**
 * 一个事例
 *
 * 一个农场,要向市场销售水果
 * 农场里有三种水果 苹果、葡萄
 * 我们设想:1、水果有多种属性,每个属性都有不同,但是,他们有共同的地方 | 生长、种植、收货、吃
 *       2、将来有可能会增加新的水果、我们需要定义一个接口来规范他们必须实现的方法
 *       3、我们需要获取某个水果的类,要从农场主那里去获取某个水果的实例,来知道如何生长、种植、收货、吃
 */
  
  
/**
 * 虚拟产品接口类
 * 定义好需要实现的方法
 */
  
interface fruit{
  
  /**
   * 生长
   */
  public function grow();
  
  /**
   * 种植
   */
  public function plant();
  
  /**
   * 收获
   */
  public function harvest();
  
  /**
   * 吃
   */
  public function eat();
    
}
  
/**
 * 定义具体产品类 苹果
 * 首先,我们要实现所继承的接口所定义的方法
 * 然后定义苹果所特有的属性,以及方法
 */
class apple implements fruit{
  
  //苹果树有年龄
  private $treeAge;
  
  //苹果有颜色
  private $color;
  
  public function grow(){
    echo "grape grow";
  }
  
  public function plant(){
    echo "grape plant";
  }
  
  public function harvest(){
    echo "grape harvest";
  }
  
  public function eat(){
    echo "grape eat";
  }
  
  //取苹果树的年龄
  public function getTreeAge(){
    return $this->treeAge;
  }
  
  //设置苹果树的年龄
  public function setTreeAge($age){
    $this->treeAge = $age;
    return trie;
  }
  
}
  
/**
 * 定义具体产品类 葡萄
 * 首先,我们要实现所继承的接口所定义的方法
 * 然后定义葡萄所特有的属性,以及方法
 */
class grape implements fruit{
  
  //葡萄是否有籽
  private $seedLess;
  
  public function grow(){
    echo "apple grow";
  }
  
  public function plant(){
    echo "apple plant";
  }
  
  public function harvest(){
    echo "apple harvest";
  }
  
  public function eat(){
    echo "apple eat";
  }
  
  //有无籽取值
  public function getSeedLess(){
    return $this->seedLess;
  }
  
  //设置有籽无籽
  public function setSeedLess($seed){
    $this->seedLess = $seed;
    return true;
  }
}
  
/**
 *农场主类 用来获取实例化的水果
 *
 */
class farmer{
  
  //定义个静态工厂方法
  public static function factory($fruitName){
    switch ($fruitName) {
      case &#39;apple&#39;:
        return new apple();
        break;
      case &#39;grape&#39;:
        return new grape();
        break;
      default:
        throw new badFruitException("Error no the fruit", 1);
        break;
    }
  }
}
  
class badFruitException extends Exception{
  public $msg;
  public $errType;
  public function __construct($msg = &#39;&#39; , $errType = 1){
    $this->msg = $msg;
    $this->errType = $errType;
  }  
}
  
/**
 * 获取水果实例化的方法
 */
try{
  $appleInstance = farmer::factory(&#39;apple&#39;);
  var_dump($appleInstance);
}catch(badFruitException $err){
  echo $err->msg . "_______" . $err->errType;
}

以下では、主に PHP デザインパターンのファクトリパターンを紹介し、ファクトリパターンの概念と原理を簡単に紹介します。ファクトリ パターンの具体的な定義と使用法を例の形で分析します。必要な友人がそれを参照できるように、すべての人に役立つことを願っています。

この記事の例では、PHP デザインパターンのファクトリーパターンについて説明します。参考のために皆さんと共有してください。詳細は次のとおりです:

ファクトリーモードを使用する目的または目標は何ですか?

ファクトリ パターンの最大の利点はオブジェクトの作成にあり、オブジェクトの作成プロセスをカプセル化して、いつでも新しいオブジェクトを生成できるようにします。

コードを減らしてコピーアンドペーストすると、結合関係が重くなり、コードの他の部分に影響を与えます。

平たく言えば、以前は new を使用してオブジェクトを作成していましたが、今ではこのプロセスがカプセル化されています。

ファクトリ モードが使用されていないと仮定します。その場合、クラス a がさまざまな場所で呼び出され、コードは次のようなインスタンスを作成します: new a() ある日、クラス a の名前を変更する必要があるとします。これは、多くの呼び出しコードを変更する必要があることを意味します。

ファクトリー パターンの利点は、オブジェクトの作成にあります。

ファクトリー パターンの利点は、オブジェクトの作成にあります。新しいオブジェクトを作成するためのファクトリ (関数またはクラス メソッド) を確立します。そのタスクは、オブジェクトの作成プロセスをカプセル化することです。

オブジェクトの作成には new の形式は使用されません。代わりに、オブジェクト インスタンスを作成するメソッドを定義します。

各クラスはデータベースに接続する必要がある場合があります。次に、データベースへの接続をクラスにカプセル化します。将来的には、他のクラスでもそのクラス名を使用してください:

なぜ抽象概念を導入するのでしょうか?

考えてみてください。実生活では、何かを具体的に決定できないとき、私たちは物事のカテゴリーを抽象的なカテゴリーに分類することがよくあります。

工場メソッド:

たとえば、工場が「タバコ工場」と呼ばれる場合、「セプトウルブズ工場」、「中国工場」などが考えられます。ただし、この工場はタバコ 1 つの製品のみを生産します。工場: 説明できません どのような製品を生産しますか? 多くの種類の製品を生産します (したがって、抽象工場はサブ工場を生成します)。

あなたの工場は総合的で、「タバコ」や「ビール」などの製品を「1 つ」ではなく「一連」に生産しています。また、それに由来する特定の工場を持つこともできますが、これらの工場はすべてこのシリーズの製品を生産していますが、地域が異なるため、また地元の好みに合わせて味が異なる場合があります。

工場パターン: 1 つの製品のみを生成する工場として理解されます。たとえば、タバコを生産する人たち。

工場方式:工場内の製品生産ライン。たとえば、キーボードの生成プロセスです。

他の人は「お腹がいっぱいになっても何もすることがないので、クラス名を変更しなければならないのですか?」と反論します。多分。通常、クラス名は変更されません。

実際、ファクトリ パターンには多くのバリエーションがあり、本質を把握することが重要です。異なるパラメータに基づいて異なるクラス インスタンスを生成できる限り、ファクトリ パターンの設計思想と一致しています。 。

これで、フレームワークには、呼び出し用の特定のクラス インスタンスの生成を担当するメソッドが存在することがよくあることを思い出しました。

私は以前に phpcms を使用したことがあるので、次のように phpcms を使用すると理解しやすくなります。

pc_base:load_app_class("order"&#39;);//参数名称就是类名称。

は order のインスタンスを生成します。異なるパラメータを渡して異なるクラス インスタンスを取得することは、ファクトリ パターンと一致しています。

pc_base:load_app_class("comment"&#39;);//生成一个comment类实例

もちろん、load_app_class メソッドにもシングルトン モードの考え方が組み込まれています。 n 回呼び出して n 個の同一のインスタンスを繰り返し作成することは避けてください

ファクトリ モードで私が考える典型的なアプリケーションは次のとおりです: PHP は mysql にリンクする必要がある場合や、sqlserver または他のデータベースにリンクする必要がある場合があります。次に、抽象データベース クラスを作成します。

このクラスは、さまざまなオブジェクトの生成を担当するファクトリ クラスです。

このように拡張するととても便利です。データベースに直接接続する場合、コード

new Mysql($host,$username,$password,$dbname)

を使用する代わりに、データベースに接続するためのインスタンスを動的に生成できます。 mysql または oracle に接続することができます。

class DbFactory
{
  function static factory($db_class_name)
  {
    $db_class_name = strtolower($db_class_name);
    if (include_once &#39;Drivers/&#39; . $db_class_name . &#39;.php&#39;) {
      $classname = &#39;Driver_&#39; . $db_class_name;
      return new $db_class_name;
    } else {
      throw new Exception (&#39;对应的数据库类没找到&#39;);
    } 
  }
}
DbFactory::factory("mysql");
DbFactory::factory("oracle");

thinkphp フレームワークにも対応する実装があります:


Db.class.php はファクトリ クラス (データベース中間層とも呼ばれます。MySQL を操作できるため中間層と呼ばれます) 、Oracle およびその他のデータベース。このクラスは、特定の実装を保護する中間層であり、元のクエリ コードを変更せずに、mysql、oracle、およびその他のデータベースに接続できます。さまざまなデータベース インスタンス

public function factory($db_config=&#39;&#39;) {
    // 读取数据库配置
    $db_config = $this->parseConfig($db_config);
    if(empty($db_config[&#39;dbms&#39;]))
      throw_exception(L(&#39;_NO_DB_CONFIG_&#39;));
    // 数据库类型
    $this->dbType = ucwords(strtolower($db_config[&#39;dbms&#39;]));
    $class = &#39;Db&#39;. $this->dbType;
    if(is_file(CORE_PATH.&#39;Driver/Db/&#39;.$class.&#39;.class.php&#39;)) {
      // 内置驱动
      $path = CORE_PATH;
    }else{ // 扩展驱动
      $path = EXTEND_PATH;
    }
    // 检查驱动类
    if(require_cache($path.&#39;Driver/Db/&#39;.$class.&#39;.class.php&#39;)) {
      $db = new $class($db_config);
      // 获取当前的数据库类型
      if( &#39;pdo&#39; != strtolower($db_config[&#39;dbms&#39;]) )
        $db->dbType = strtoupper($this->dbType);
      else
        $db->dbType = $this->_getDsnType($db_config[&#39;dsn&#39;]);
      if(APP_DEBUG) $db->debug  = true;
    }else {
      // 类没有定义
      throw_exception(L(&#39;_NOT_SUPPORT_DB_&#39;).&#39;: &#39; . $db_config[&#39;dbms&#39;]);
    }
    return $db;
}

と、将来的には、Alipay、Tenpay、オンライン バンキングなどのさまざまな支払いゲートウェイに対応する可能性があります。将来の拡張を容易にするために、専用のプロダクション ゲートウェイが設計されています。は抽象化されてインターフェイス フォームに作成されるため、将来的にはすべてのサブクラスでそのインターフェイスを実装する必要があり、支払い方法を追加し、パラメータを変更して使用する支払い方法を決定できます。

書籍「php Authoritative Programming」(英語名は PHP 5 Power Programming) にも、ユーザーを登録するときに多くの役割を持つユーザーに分割するというコツが記載されています。登録ユーザー、匿名ユーザー、管理者ユーザーなど。ファクトリの考え方で完全な利用が可能で、コードのメンテナンスも容易で、ロールごとに操作クラスを生成できます。

次のクラスを定義します:

UserFactory ユーザー ファクトリ クラス、さまざまなユーザー クラスの生成を担当します
User: ユーザー クラスの基本クラス、すべてのユーザー クラスはこのクラスを継承します
異なる役割を持つクラス: 登録済みユーザー クラス、匿名ユーザー クラス、管理者ユーザークラス

関連する推奨事項:

JS抽象ファクトリパターンの簡単な分析_基礎知識

phpデザインパターンファクトリパターンの役割は何ですか?

3つのPHPファクトリーモードの簡単な紹介

以上がPHPの簡易ファクトリパターンとファクトリパターンのまとめの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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