1. 程式人生 > 程式設計 >php設計模式之工廠方法模式分析【星際爭霸遊戲案例】

php設計模式之工廠方法模式分析【星際爭霸遊戲案例】

本文例項講述了php設計模式之工廠方法模式。分享給大家供大家參考,具體如下:

PHP手冊上提到的工廠模式,其實是簡單工廠模式。這裡來討論簡單工廠模式的擴充套件:工廠方法模式。

待解決的問題:雖然簡單工廠解決了動態返回不同型別物件的問題,但是實際情況當中,往往在新建一個物件的時候,需要做一些額外處理,比如製造機槍兵的時候需要判斷水晶礦是否大於50,而製造火焰兵的時候需要同時判斷水晶礦是否大於50和氣礦大於25,還有是否建造了研究院。如果把這些程式碼全部放到工廠製造類裡面,會使得製造類很臃腫,而且隨著工廠生產的物件的種類越來越多,工廠製造類的程式碼會越來越難以維護。

思路:簡單工廠模式中的工廠類(兵種製造器的類)保持不變,增加一個製造介面,定義一個實際製造物件的方法,然後定義各個具體制造不同物件的工廠,同時要求這些工廠執行這個製造介面,讓這些工廠去實現實際製造物件的方法。

工廠方法模式示例:

我們把機槍兵類和製造機槍兵的類的程式碼放入一個檔案,Marine.php,它的程式碼如下:

<?php
  //機槍兵類
  class Marine
  {
    //機槍兵攻擊的方法
    public function attack()
    {
      echo 'Marine attack';
    }
  }
  //製造機槍兵的類,執行介面abstractCreator
  class MarineCreator implements abstractCreator
  {
    //實際製造機槍兵的方法
    public function realCreate()
    {
      //如果水晶礦大於50,這裡只是作為說明,因為並不存在ore這個變數,也不考慮水晶少於50的處理
      if($ore>50)
      {
        return new Marine();
      }
    }
  }
?>

我們把火焰兵類和製造火焰兵的類的程式碼放入一個檔案,Firebat.php,它的程式碼如下:

<?php
  //火焰兵類
  class Firebat
  {
    //火焰兵攻擊的方法
    public function attack()
    {
      echo 'Firebat attack';
    }
  }
  //製造火焰兵的類,執行介面abstractCreator
  class FirebatCreator implements abstractCreator
  {
    //實際製造火焰兵的方法
    public function realCreate()
    {
      //如果水晶礦大於50同時氣礦大於25,並且研究院已經存在。這裡只是作為說明,因為並不存在ore和gas和Academy變數,也不考慮資源不夠時的處理
      if($ore>50 && $gas>25 && Academy>1)
      {
        return new Firebat();
      }
    }
  }
?>

主檔案中的內容如下:

<?php
  //各個具體工廠必須執行的介面
  interface abstractCreator
  {
    //規定各個具體工廠要實現的方法
    public function realCreate();
  }
  //兵種製造器的類,也就是主工廠
  class BarracksCreator
  {
    //製造兵種的方法
    public create($createWhat)
    {
      //根據輸入的引數,動態的把需要的類的定義檔案載入
      require_once($createWhat.'.php');
      //根據輸入的引數,動態的獲取相應的具體工廠的類的名字
      $creatorClassName = $createWhat.'Creator';
      //新建具體工廠物件
      $creator = new $creatorClassName;
      //用具體工廠來實際生產,然後返回需要的類的物件。因為它們都執行了介面abstractCreator,所以肯定實現了方法realCreate()
      return $creator->realCreate();
    }
  }
  //新建一個兵種製造器物件
  $creator = new BarracksCreator();
  //靠接收引數製造一個火焰兵物件
  $troop1 = $creator->create('Marine');
  $troop1->attack();
  //靠接收引數製造一個機槍兵物件
  $troop2 = $creator->create('Firebat');
  $troop2->attack();
?>

用途總結:工廠方法模式將新建物件的任務將給對應的具體工廠類,不必因為某些生產的物件需要進行額外處理而修改對外的主工廠。

實現總結:需要接收引數的主工廠類,比如上面兵種製造器BarracksCreator,還需要宣告具體制造方法的一個介面,比如上面abstractCreator,然後定義具體生產各個產品的具體工廠類,每個具體工廠類必須執行介面abstractCreator,這樣他們就必須實現製造物件的方法,比如上面的realCreate()。使用的時候只需要將引數傳遞給主工廠類工廠的生產方法create(),然後由create()根據引數生成具體工廠類的物件,並呼叫具體工廠類realCreate()獲取製造的產品物件並返回,對外界使用來說,只需呼叫主工廠類工廠進行生產。
說明:其實這篇文章內的工廠方法模式和有些文章寫的不同,標準的工廠模式往往是用一個抽象類來代替上面的介面abstractCreator,然後讓所有的具體工廠類來繼承它,但使用的時候,由於抽象類不能例項化(新建它的物件),所以經常是程式碼中直接new FirebatCreator(),但是簡單工廠模式可以解決直接new的問題,所以我這裡將簡單工廠模式和工廠方法模式一起使用,使這裡的示例更加實用。同時由於PHP是單繼承,而執行介面的數量是沒有限制的,所以使用介面abstractCreator更加靈活。

更多關於PHP相關內容感興趣的讀者可檢視本站專題:《php面向物件程式設計入門教程》、《PHP陣列(Array)操作技巧大全》、《PHP基本語法入門教程》、《PHP運算與運算子用法總結》、《php字串(string)用法總結》、《php+mysql資料庫操作入門教程》及《php常見資料庫操作技巧彙總》

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