佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > PHP設計模式(一)工廠模式Factory實例詳解【創(chuàng)建型】

PHP設計模式(一)工廠模式Factory實例詳解【創(chuàng)建型】

熱門標簽:團購網站 科大訊飛語音識別系統(tǒng) Linux服務器 電子圍欄 服務器配置 阿里云 Mysql連接數(shù)設置 銀行業(yè)務

本文實例講述了PHP設計模式(一)工廠模式Factory。分享給大家供大家參考,具體如下:

在面向對象編程中, 最通常的方法是一個new操作符產生一個對象實例,new操作符就是用來構造對象實例的。但是在一些情況下, new操作符直接生成對象會帶來一些問題。舉例來說, 許多類型對象的創(chuàng)造需要一系列的步驟: 你可能需要計算或取得對象的初始設置; 選擇生成哪個子對象實例; 或在生成你需要的對象之前必須先生成一些輔助功能的對象。 在這些情況,新對象的建立就是一個 “過程”,不僅是一個操作,像一部大機器中的一個齒輪傳動。

模式的問題:你如何能輕松方便地構造對象實例,而不必關心構造對象實例的細節(jié)和復雜過程呢?

解決方案:建立一個工廠來創(chuàng)建對象。

實現(xiàn):

一、引言

    1)還沒有工廠時代:假如還沒有工業(yè)革命,如果一個客戶要一款寶馬車,一般的做法是客戶去創(chuàng)建一款寶馬車,然后拿來用。
    2)簡單工廠模式:后來出現(xiàn)工業(yè)革命。用戶不用去創(chuàng)建寶馬車。因為客戶有一個工廠來幫他創(chuàng)建寶馬.想要什么車,這個工廠就可以建。比如想要320i系列車。工廠就創(chuàng)建這個系列的車。即工廠可以創(chuàng)建產品。
    3)工廠方法模式時代:為了滿足客戶,寶馬車系列越來越多,如320i,523i,30li等系列一個工廠無法創(chuàng)建所有的寶馬系列。于是由單獨分出來多個具體的工廠。每個具體工廠創(chuàng)建一種系列。即具體工廠類只能創(chuàng)建一個具體產品。但是寶馬工廠還是個抽象。你需要指定某個具體的工廠才能生產車出來。
    4)抽象工廠模式時代:隨著客戶的要求越來越高,寶馬車必須配置空調。而且這空調必須對應給系列車才能使用。于是這個工廠開始生產寶馬車和需要的空調。
         最終是客戶只要對寶馬的銷售員說:我要523i空調車,銷售員就直接給他523i空調車了。而不用自己去創(chuàng)建523i空調車寶馬車.
   (我只是舉個例子,說到寶馬配置空調完全是為了舉例,甚至有點扯,哪有車和空調必須對應才能使用?。?br />      這就是工廠模式。

二、分類 

        工廠模式主要是為創(chuàng)建對象提供過渡接口,以便將創(chuàng)建對象的具體過程屏蔽隔離起來,達到提高靈活性的目的。 
工廠模式可以分為三類: 
1)簡單工廠模式(Simple Factory) 
2)工廠方法模式(Factory Method) 
3)抽象工廠模式(Abstract Factory) 
         這三種模式從上到下逐步抽象,并且更具一般性。 
        GOF在《設計模式》一書中將工廠模式分為兩類:工廠方法模式(Factory Method)與抽象工廠模式(Abstract Factory)。將簡單工廠模式(Simple Factory)看為工廠方法模式的一種特例,兩者歸為一類。

三、區(qū)別 

工廠方法模式:
一個抽象產品類,可以派生出多個具體產品類。   
一個抽象工廠類,可以派生出多個具體工廠類。   
每個具體工廠類只能創(chuàng)建一個具體產品類的實例。

抽象工廠模式:
多個抽象產品類,每個抽象產品類可以派生出多個具體產品類。   
一個抽象工廠類,可以派生出多個具體工廠類。
每個具體工廠類可以創(chuàng)建多個具體產品類的實例。

區(qū)別:
工廠方法模式只有一個抽象產品類,而抽象工廠模式有多個。   
工廠方法模式的具體工廠類只能創(chuàng)建一個具體產品類的實例,而抽象工廠模式可以創(chuàng)建多個。
兩者皆可。 

四、簡單工廠模式

建立一個工廠(一個函數(shù)或一個類方法)來制造新的對象。

分布說明引子:從無到有??蛻糇约簞?chuàng)建寶馬車,然后拿來用。

?php
/**
 * 車子系列
 *
 */
Class BWM320{
function __construct($pa) {
 
}
}
Class BMW523{
  function __construc($pb){
}
}
/**
 * 
 * 客戶自己創(chuàng)建寶馬車
 */
class Customer {
 
  function createBMW320(){
    return new BWM320();
  }
 
  function createBMW523(){
    return new BMW523();
  }
} 

       客戶需要知道怎么去創(chuàng)建一款車,客戶和車就緊密耦合在一起了.為了降低耦合,就出現(xiàn)了工廠類,把創(chuàng)建寶馬的操作細節(jié)都放到了工廠里面去,客戶直接使用工廠的創(chuàng)建工廠方法,傳入想要的寶馬車型號就行了,而不必去知道創(chuàng)建的細節(jié).這就是工業(yè)革命了:簡單工廠模式

即我們建立一個工廠類方法來制造新的對象。如圖:

產品類:

?php
/**
 * 車子系列
 *
 */
abstract Class BWM{
  function __construct($pa) {
 
  }
}
Class BWM320 extends BWM{
  function __construct($pa) {
 
  }
}
Class BMW523 extends BWM{
  function __construc($pb){
 
  }
}

工廠類:

/**
 * 
 * 工廠創(chuàng)建車
 */
class Factory {
  static function createBMW($type){
    switch ($type) {
     case 320:
       return new BWM320();
     case 523:
       return new BMW523();
    //....
  }
}

客戶類:

/**
 * 
 * 客戶通過工廠獲取車
 */
class Customer {
  private $BMW;
  function getBMW($type){
    $this¬-> BMW = Factory::createBMW($type);
  }
}

      簡單工廠模式又稱靜態(tài)工廠方法模式。重命名上就可以看出這個模式一定很簡單。它存在的目的很簡單:定義一個用于創(chuàng)建對象的接口。 

      先來看看它的組成: 
         1) 工廠類角色:這是本模式的核心,含有一定的商業(yè)邏輯和判斷邏輯。
         2) 抽象產品角色:它一般是具體產品繼承的父類或者實現(xiàn)的接口。         
         3) 具體產品角色:工廠類所創(chuàng)建的對象就是此角色的實例。在java中由一個具體類實現(xiàn)。 

        下面我們從開閉原則(對擴展開放;對修改封閉)上來分析下簡單工廠模式。當客戶不再滿足現(xiàn)有的車型號的時候,想要一種速度快的新型車,只要這種車符合抽象產品制定的合同,那么只要通知工廠類知道就可以被客戶使用了。所以對產品部分來說,它是符合開閉原則的;但是工廠部分好像不太理想,因為每增加一種新型車,都要在工廠類中增加相應的創(chuàng)建業(yè)務邏輯(createBMW($type)方法需要新增case),這顯然是違背開閉原則的。可想而知對于新產品的加入,工廠類是很被動的。對于這樣的工廠類,我們稱它為全能類 或者上帝類。 
        我們舉的例子是最簡單的情況,而在實際應用中,很可能產品是一個多層次的樹狀結構。由于簡單工廠模式中只有一個工廠類來對應這些產品,所以這可能會把我們的上帝累壞了,也累壞了我們這些程序員:( 
        于是工廠方法模式作為救世主出現(xiàn)了。 工廠類定義成了接口,而每新增的車種類型,就增加該車種類型對應工廠類的實現(xiàn),這樣工廠的設計就可以擴展了,而不必去修改原來的代碼。

五、工廠方法模式 

        工廠方法模式去掉了簡單工廠模式中工廠方法的靜態(tài)屬性,使得它可以被子類繼承。這樣在簡單工廠模式里集中在工廠方法上的壓力可以由工廠方法模式里不同的工廠子類來分擔。 
工廠方法模式組成: 

       1)抽象工廠角色: 這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現(xiàn)的接口或者必須繼承的父類。在java中它由抽象類或者接口來實現(xiàn)。 
       2)具體工廠角色:它含有和具體業(yè)務邏輯有關的代碼。由應用程序調用以創(chuàng)建對應的具體產品的對象。 
       3)抽象產品角色:它是具體產品繼承的父類或者是實現(xiàn)的接口。在java中一般有抽象類或者接口來實現(xiàn)。 
       4)具體產品角色:具體工廠角色所創(chuàng)建的對象就是此角色的實例。在java中由具體的類來實現(xiàn)。 
       工廠方法模式使用繼承自抽象工廠角色的多個子類來代替簡單工廠模式中的“上帝類”。正如上面所說,這樣便分擔了對象承受的壓力;而且這樣使得結構變得靈活 起來——當有新的產品產生時,只要按照抽象產品角色、抽象工廠角色提供的合同來生成,那么就可以被客戶使用,而不必去修改任何已有 的代碼??梢钥闯龉S角色的結構也是符合開閉原則的! 

代碼如下: 

產品類:

?php
/**
 * 車子系列
 *
 */
abstract Class BWM{
function __construct($pa) {
}
}
Class BWM320 extends BWM{
function __construct($pa) {
}
}
Class BMW523 extends BWM{
  function __construc($pb){
}
}

創(chuàng)建工廠類:

/**
 * 創(chuàng)建工廠的接口
 *
 */
interface FactoryBMW { 
    function createBMW(); 
} 
/**
 * 
 * 創(chuàng)建BWM320車
 */
class FactoryBWM320 implements FactoryBMW {
  function createBMW($type){
   return new BWM320();
  }
}
/**
 * 
 * 創(chuàng)建BWM523車
 */
class FactoryBWM523 implements FactoryBMW {
  function createBMW($type){
   return new BMW523();
  }
}

客戶類:

/**
 * 
 * 客戶得到車
 */
class Customer {
  private $BMW;
  function getBMW($type){
   switch ($type) {
    case 320:
      $BWM320 = new FactoryBWM320();
      return $BWM320->createBMW();
    case 523:
      $BWM523 = new FactoryBWM523();
      return $BWM320->createBMW();
      //....
   }
 
 }
}

       可以看出工廠方法的加入,使得對象的數(shù)量成倍增長。當產品種類非常多時,會出現(xiàn)大量的與之對應的工廠對象,這不是我們所希望的。因為如果不能避免這種情 況,可以考慮使用簡單工廠模式與工廠方法模式相結合的方式來減少工廠類:即對于產品樹上類似的種類(一般是樹的葉子中互為兄弟的)使用簡單工廠模式來實 現(xiàn)。

工廠方法小結:

        工廠方法模式仿佛已經很完美的對對象的創(chuàng)建進行了包裝,使得客戶程序中僅僅處理抽象產品角色提供的接口。那我們是否一定要在代碼中遍布工廠呢?大可不必。也許在下面情況下你可以考慮使用工廠方法模式: 

     1)當客戶程序不需要知道要使用對象的創(chuàng)建過程。 
     2)客戶程序使用的對象存在變動的可能,或者根本就不知道使用哪一個具體的對象。

       簡單工廠模式與工廠方法模式真正的避免了代碼的改動了?沒有。在簡單工廠模式中,新產品的加入要修改工廠角色中的判斷語句;而在工廠方法模式中,要么將判 斷邏輯留在抽象工廠角色中,要么在客戶程序中將具體工廠角色寫死(就象上面的例子一樣)。而且產品對象創(chuàng)建條件的改變必然會引起工廠角色的修改。
       面對這種情況,我們可以使用反射機制:

 class Customer {
   private $BMW;
   function getBMW($type){
     $class = new ReflectionClass('FactoryBWM' .$type );//建立 'FactoryBWM'這個類的反射類 
     $instance = $class->newInstanceArgs();//相當于實例化'FactoryBWM' .$type類 
     return $instance->createBMW();
    //或者直接 
     /**
     * $instance = new 'FactoryBWM' .$type();
     * return $instance->createBMW();
     */
  }
}

六、抽象工廠模式

       隨著客戶的要求越來越高,寶馬車需要配置空調。于是這個工廠開始生產寶馬車和配置需要的空調。這時候工廠有二個系列的產品:寶馬車和空調.寶馬車必須使用對應的空調才能使用.這時候分別使用一個車工廠和一個空調工廠都不能滿足我們的需求,我們必須確認車跟空調的對應關系。因此把車工廠跟空調工廠聯(lián)系在一起。因此出現(xiàn)了抽象工廠模式。

     可以說,抽象工廠模式和工廠方法模式的區(qū)別就在于需要創(chuàng)建對象的復雜程度上。而且抽象工廠模式是三個里面最為抽象、最具一般性的。

抽象工廠模式的用意為:給客戶端提供一個接口,可以創(chuàng)建多個產品族中的產品對象 ,而且使用抽象工廠模式還要滿足一下條件:

     1)系統(tǒng)中有多個產品族,而系統(tǒng)一次只可能消費其中一族產品。
     2)同屬于同一個產品族的產品以其使用。

抽象工廠模式的各個角色(和工廠方法一樣):

     1)抽象工廠角色: 這是工廠方法模式的核心,它與應用程序無關。是具體工廠角色必須實現(xiàn)的接口或者必須繼承的父類。在java中它由抽象類或者接口來實現(xiàn)。 
     2)具體工廠角色:它含有和具體業(yè)務邏輯有關的代碼。由應用程序調用以創(chuàng)建對應的具體產品的對象。
     3)抽象產品角色:它是具體產品繼承的父類或者是實現(xiàn)的接口。
     4)具體產品角色:具體工廠角色所創(chuàng)建的對象就是此角色的實例。

其結構:

我們的例子:

代碼:

產品類:

?php
/**
 * 車子系列以及型號
 *
 */
abstract class BWM{
}
class BWM523 extends BWM {
}
class BWM320 extends BWM {
}
/**
 * 空調
 *
 */
abstract class aircondition{
}
class airconditionBWM320 extends aircondition {
}
class airconditionBWM52 extends aircondition {
}

創(chuàng)建工廠類:

/**
 * 創(chuàng)建工廠的接口
 *
 */
interface FactoryBMW { 
   function createBMW(); 
   function createAirC(); 
} 
/**
 * 
 * 創(chuàng)建BWM320車
 */
class FactoryBWM320 implements FactoryBMW {
  function createBMW(){
  return new BWM320();
}
function createAirC(){ //空調
  return new airconditionBWM320();
}
}
/**
 * 
 * 創(chuàng)建BWM523車
 */
class FactoryBWM523 implements FactoryBMW {
  function createBMW(){
  return new BWM523();
}
function createAirC(){
  return new airconditionBWM523();
}
}
 

客戶:

/**
 * 
 * 客戶得到車
 */
class Customer {
  private $BMW;
  private $airC;
  function getBMW($type){
    $class = new ReflectionClass('FactoryBWM' .$type );//建立 Person這個類的反射類 
    $instance = $class->newInstanceArgs();//相當于實例化Person 類 
    $this->BMW = $instance->createBMW();
    $this->airC = $instance->createAirC();
  }
}

更多關于PHP相關內容感興趣的讀者可查看本站專題:《php面向對象程序設計入門教程》、《PHP數(shù)組(Array)操作技巧大全》、《PHP基本語法入門教程》、《PHP運算與運算符用法總結》、《php字符串(string)用法總結》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總》

希望本文所述對大家PHP程序設計有所幫助。

您可能感興趣的文章:
  • PHP設計模式之原型模式示例詳解
  • PHP設計模式之命令模式示例詳解
  • PHP設計模式(四)原型模式Prototype實例詳解【創(chuàng)建型】
  • PHP設計模式(三)建造者模式Builder實例詳解【創(chuàng)建型】
  • PHP設計模式概論【概念、分類、原則等】
  • PHP設計模式之 策略模式Strategy詳解【對象行為型】
  • PHP設計模式入門之狀態(tài)模式原理與實現(xiàn)方法分析
  • PHP設計模式入門之迭代器模式原理與實現(xiàn)方法分析
  • PHP設計模式之迭代器模式Iterator實例分析【對象行為型】
  • php設計模式之適配器模式實例分析【星際爭霸游戲案例】
  • php設計模式之迭代器模式實例分析【星際爭霸游戲案例】
  • 詳解PHP八大設計模式

標簽:棗莊 蚌埠 江蘇 萍鄉(xiāng) 衡水 大理 衢州 廣元

巨人網絡通訊聲明:本文標題《PHP設計模式(一)工廠模式Factory實例詳解【創(chuàng)建型】》,本文關鍵詞  ;如發(fā)現(xiàn)本文內容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內容系統(tǒng)采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    封丘县| 盐亭县| 海盐县| 柘城县| 梅河口市| 准格尔旗| 蕉岭县| 台江县| 泸州市| 龙州县| 瓦房店市| 泰宁县| 子长县| 陕西省| 峨边| 无极县| 北宁市| 若尔盖县| 崇义县| 阳江市| 庐江县| 江山市| 磐安县| 苍山县| 云和县| 进贤县| 壶关县| 汤原县| 宣汉县| 博罗县| 阿尔山市| 岐山县| 闻喜县| 大邑县| 达尔| 平邑县| 阿克| 马边| 北川| 策勒县| 河北省|