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程式設計有所幫助。