首頁  >  文章  >  後端開發  >  PHP簡單工廠模式與工廠模式總結

PHP簡單工廠模式與工廠模式總結

小云云
小云云原創
2018-01-25 17:01:441355瀏覽

首先我們先看一下簡單工廠模式,程式碼如下:

<?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的形式了。而是定義一個方法,用來建立物件實例。

每個類別可能會需要連接資料庫。那麼就將連接資料庫封裝在一個類別中。以後在其他類別中透過類別名稱:

為什麼要引入抽象的概念?

想一想,在現實生活中,當我們無法確定某個具體的東西的時候,往往把一類東西歸於抽象類別。

工廠方法:

例如你的工廠叫做“香煙工廠”,那麼可以有“七匹狼工廠”“中華工廠”等,但是,這個工廠只生廠一種商品:香煙;

抽象工廠:無法描述它到底生產什麼產品,它生產很多類型的產品(所以抽象工廠就會生成子工廠)。

你的工廠是綜合型的,是生產“一系列”產品,而不是“一個”,例如:生產“香煙”,還有“啤酒”等。然後它也可以有衍生出來的具體的工廠,但這些工廠都是生產這一系列產品,只是可能因為地理不一樣,為了適應當地人口味,味道也不太一樣。

工廠模式:理解成只生成一種產品的工廠。比如生產香煙的。

工廠方法:工廠的一種產品生產線 。比如鍵盤的生成過程。

別人會反駁:吃飽了沒事幹,一定要修改類別名稱呢?這個說不定。一般都不會去修改類別名稱。

其實工廠模式有很多變體,抓住精髓才是關鍵:只要是可以根據不同的參數產生不同的類別實例,那就符合工廠模式的設計想法。

這樣子讓我聯想到框架中常常會有負責產生具體類別實例的方法供呼叫。

由於前面使用過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等各資料庫。

Db.class.php中有個factory()方法來建立不同的資料庫實例


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;
}

還有做支付介面的時候,未來可能對應不同的支付網關:支付寶、財付通、網銀在線等。的子類別都要實現它的介面。

書籍4935408f8984d367680b18b43f40f150(英文名稱為PHP 5 Power Programming)也提到一個工廠模式的例子,學到一招:在為使用者註冊的時候,分成許多角色的使用者。例如冊用戶,匿名用戶、管理員用戶等。完全使用可以使用工廠的思想來實現,代碼也容易維護,為每種角色可以生成操作的類別。

定義以下幾個類別:

UserFactory 使用者工廠類,負責產生不同的使用者類別
User:使用者類別的基底類,所有使用者類別都是繼承這個類別
不同角色的類別:註冊使用者類別、匿名使用者類別、管理員使用者類別

相關推薦:

#JS抽象工廠模式_基礎知識

############################################## #######php設計模式工廠模式有什麼作用? ############三種php工廠模式的簡單介紹#######

以上是PHP簡單工廠模式與工廠模式總結的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn