您好,登錄后才能下訂單哦!
小編給大家分享一下PHP設(shè)計模式中工廠模式的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
簡單工廠模式是類的創(chuàng)建模式,又叫做靜態(tài)工廠方法(Static Factory Method)模式。簡單工廠模式是由一個工廠對象決定創(chuàng)建出那一種產(chǎn)品類的實例。
1.工廠模式的幾種形態(tài)
工廠模式專門負責將大量有共同接口的類實例化。工廠模式可以動態(tài)決定將哪一個類實例化,不必事先知道每次要實例化哪一個類。工廠模式有以下幾種形態(tài):
(1)簡單工廠(Simple Factory)模式,又稱靜態(tài)工廠方法模式(Static Factory Method Pattern)。
(2)工廠方法(Factory Method)模式,又稱多態(tài)性工廠(Polymorphic Factory)模式或虛擬構(gòu)造子(Virtual Constructor)模式;
(3)抽象工廠(Abstract Factory)模式,又稱工具箱(Kit 或Toolkit)模式。下面就是簡單工廠模式的簡略類圖。
簡單工廠模式,或稱靜態(tài)工廠方法模式,是不同的工廠方法模式的一個特殊實現(xiàn)。在其他文獻中,簡單工廠往往作為普通工廠模式的一個特例討論。
學(xué)習簡單工廠模式是對學(xué)習工廠方法模式的一個很好的準備,也是對學(xué)習其他模式,特別是單例模式和多例模式的一個很好的準備。
2 .簡單工廠模式的引進
比如說有一個農(nóng)場公司,專門向市場銷售各類水果。在這個系統(tǒng)里需要描述下列的水果:
葡萄 Grape
草莓 Strawberry
蘋果 Apple
水果與其他的植物有很大的不同,就是水果最終是可以采摘食用的。那么一個自然的作法就是建立一個各種水果都適用的接口,以便與農(nóng)場里的其他植物區(qū)分開。如下圖所示。
水果接口規(guī)定出所有的水果必須實現(xiàn)的接口,包括任何水果類必須具備的方法:種植plant(),生長grow()以及收獲harvest()。接口Fruit 的類圖如下所示。
這個水果接口的源代碼如下所示。
代碼清單1:接口Fruit 的源代碼
interface Fruit { public function grow(); public function harvest(); public function plant(); }
Apple 類是水果類的一種,因此它實現(xiàn)了水果接口所聲明的所有方法。另外,由于蘋果是多年生植物,因此多出一個treeAge 性質(zhì),描述蘋果樹的樹齡。下面是這個蘋果類的源代碼。
代碼清單2:類Apple 的源代碼
class Apple implements Fruit { private $_treeAge; public function grow() { echo "Apple is growing."; } public function harvest() { echo "Apple has been harvested."; } public function plant() { echo "Apple has been planted."; } public function getTreeAge() { return $this->_treeAge; } public function setTreeAge($treeAge) { $this->_treeAge = (int) $treeAge; } }
同樣,Grape 類是水果類的一種,也實現(xiàn)了Fruit 接口所聲明的所有的方法。但由于葡萄分有籽和無籽兩種,因此,比通常的水果多出一個seedless 性質(zhì),如下圖所示。
葡萄類的源代碼如下所示??梢钥闯?,Grape 類同樣實現(xiàn)了水果接口,從而是水果類型的一種子類型。
代碼清單3:類Grape 的源代碼
class Grape implements Fruit { private $seedless; public function grow() { echo "Grape is growing."; } public function harvest() { echo "Grape has been harvested."; } public function plant() { echo "Grape has been planted."; } public function getSeedless() { return $this->seedless; } public function setSeedless($seedless) { $this->seedless = (boolean) $seedless; } }
Strawberry 類實現(xiàn)了Fruit 接口,因此,也是水果類型的子類型,其源代碼如下所示。
代碼清單4:類Strawberry 的源代碼
class Strawberry implements Fruit { public function grow() { echo "Strawberry is growing."; } public function harvest() { echo "Strawberry has been harvested."; } public function plant() { echo "Strawberry has been planted."; } }
農(nóng)場的園丁也是系統(tǒng)的一部分,自然要由一個合適的類來代表。這個類就是FruitGardener 類,其結(jié)構(gòu)由下面的類圖描述。
FruitGardener 類會根據(jù)客戶端的要求,創(chuàng)建出不同的水果對象,比如蘋果(Apple),葡萄(Grape)或草莓(Strawberry)的實例。而如果接到不合法的要求,F(xiàn)ruitGardener 類會拋出BadFruitException 異常。
園丁類的源代碼如下所示。
代碼清單5:FruitGardener 類的源代碼
class FruitGardener { public static function factory($which) { $which = strtolower($which); if ($which == 'apple') { return new Apple(); } elseif ($which == 'strawberry') { return new Strawberry(); } elseif ($which == 'grape') { return new Grape(); } else { throw new BadFruitException('Bad fruit request'); } } }
可以看出,園丁類提供了一個靜態(tài)工廠方法。在客戶端的調(diào)用下,這個方法創(chuàng)建客戶端所需要的水果對象。如果客戶端的請求是系統(tǒng)所不支持的,工廠方法就會拋出一個BadFruitException 異常。這個異常類的源代碼如下所示。
代碼清單6:BadFruitException 類的源代碼
class BadFruitException extends Exception { }
在使用時,客戶端只需調(diào)用FruitGardener 的靜態(tài)方法factory()即可。請見下面的示意
性客戶端源代碼。
代碼清單7:怎樣使用異常類BadFruitException
try { FruitGardener::factory('apple'); FruitGardener::factory('grape'); FruitGardener::factory('strawberry'); //... } catch (BadFruitException $e) { //... }
這樣,農(nóng)場一定會百果豐收啦!
3.使用簡單工廠模式設(shè)計一個“面向?qū)ο蟮摹庇嬎闫?/strong>
/** * 面向?qū)ο笥嬎闫? * 思路: * 1、面向?qū)ο蟮幕?,封裝、繼承、多太 * 2、父類公用類 * 3、各種運算類 */ /** * 基類,運算類 * 只提供基本數(shù)據(jù),不參與運算 */ class Operation { // 第一個數(shù) public $first_num = 0; // 第二個數(shù) public $second_num = 0; /** * 獲取結(jié)果,其他類覆蓋此方法 * @return double $result */ public function getResult() { $result = 0.00; return $result; } } /** * 加法類 */ class OperationAdd extends Operation { /** * 覆蓋父類,實現(xiàn)加法算法 */ public function getResult() { $result = 0; return $this->first_num + $this->second_num; } } /** * 減法類 * */ class OperationSub extends Operation { /** * 覆蓋父類,實現(xiàn)加法算法 */ public function getResult() { $result = 0; return $this->first_num - $this->second_num; } } /** * 乘法類 * */ class OperationMul extends Operation { /** * 覆蓋父類,實現(xiàn)加法算法 */ public function getResult() { $result = 0; return $this->first_num * $this->second_num; } } /** * 除類 * */ class OperationDiv extends Operation { /** * 覆蓋父類,實現(xiàn)加法算法 */ public function getResult() { $result = 0; if ($this->second_num == 0) { throw new Exception('除法操作第二個參數(shù)不能為零!'); return 0; } return $this->first_num / $this->second_num; } } /** * 工廠類 */ class OperationFactory { /** * 工廠函數(shù) * @param string $operation * @return object */ public function createOperation($operation) { $oper = null; switch($operation) { case '+': $oper = new OperationAdd(); break; case '-': $oper = new OperationSub(); break; case '*': $oper = new OperationMul(); break; case '/': $oper = new OperationDiv(); break; default: return 0; } return $oper; } } $operation = new OperationFactory(); $oper = $operation->createOperation('/'); $oper->first_num = 10; $oper->second_num = 20; var_dump($oper->getResult());
以上是“PHP設(shè)計模式中工廠模式的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。