執行個體講解PHP設計模式編程中的簡單原廠模式_php執行個體

來源:互聯網
上載者:User

簡單原廠模式是類的建立模式,又叫做靜態Factory 方法(Static Factory Method)模式。簡單原廠模式是由一個工廠對象決定建立出那一種產品類的執行個體。

1.原廠模式的幾種形態
原廠模式專門負責將大量有共同介面的類執行個體化。原廠模式可以動態決定將哪一個類執行個體化,不必事Crowdsourced Security Testing道每次要執行個體化哪一個類。原廠模式有以下幾種形態:
(1)簡單工廠(Simple Factory)模式,又稱靜態Factory 方法模式(Static Factory Method Pattern)。
(2)Factory 方法(Factory Method)模式,又稱多態性工廠(Polymorphic Factory)模式或虛擬構造子(Virtual Constructor)模式;
(3)抽象工廠(Abstract Factory)模式,又稱工具箱(Kit 或Toolkit)模式。下面就是簡單原廠模式的簡略類圖。

簡單原廠模式,或稱靜態Factory 方法模式,是不同的Factory 方法模式的一個特殊實現。在其他文獻中,簡單工廠往往作為普通原廠模式的一個特例討論。
學習簡單原廠模式是對學習Factory 方法模式的一個很好的準備,也是對學習其他模式,特別是單例模式和多例模式的一個很好的準備。

2 .簡單原廠模式的引進

比如說有一個農場公司,專門向市場銷售各類水果。在這個系統裡需要描述下列的水果:
葡萄 Grape
草莓 Strawberry
蘋果 Apple
水果與其他的植物有很大的不同,就是水果最終是可以採摘食用的。那麼一個自然的作法就是建立一個各種水果都適用的介面,以便與農場裡的其他植物區分開。如下圖所示。

水果介面規定出所有的水果必須實現的介面,包括任何水果類必須具備的方法:種植plant(),生長grow()以及收穫harvest()。介面Fruit 的類圖如下所示。

這個水果介面的原始碼如下所示。
代碼清單1:介面Fruit 的原始碼

interface Fruit{public function grow();public function harvest();public function plant();}

Apple 類是水果類的一種,因此它實現了水果介面所聲明的所有方法。另外,由於蘋果是多年生植物,因此多出一個treeAge 性質,描述蘋果樹的樹齡。下面是這個蘋果類的原始碼。
代碼清單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 類是水果類的一種,也實現了Fruit 介面所聲明的所有的方法。但由於葡萄分有籽和無籽兩種,因此,比通常的水果多出一個seedless 性質,如下圖所示。

葡萄類的原始碼如下所示。可以看出,Grape 類同樣實現了水果介面,從而是水果類型的一種子類型。
代碼清單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 類實現了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.";}}

農場的園丁也是系統的一部分,自然要由一個合適的類來代表。這個類就是FruitGardener 類,其結構由下面的類圖描述。

FruitGardener 類會根據用戶端的要求,建立出不同的水果對象,比如蘋果(Apple),葡萄(Grape)或草莓(Strawberry)的執行個體。而如果接到不合法的要求,FruitGardener 類會拋出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');}}}

可以看出,園丁類提供了一個靜態Factory 方法。在用戶端的調用下,這個方法建立用戶端所需要的水果對象。如果用戶端的請求是系統所不支援的,Factory 方法就會拋出一個BadFruitException 異常。這個異常類的原始碼如下所示。
代碼清單6:BadFruitException 類的原始碼

class BadFruitException extends Exception{}

在使用時,用戶端只需調用FruitGardener 的靜態方法factory()即可。請見下面的示意
性用戶端原始碼。
代碼清單7:怎樣使用異常類BadFruitException

try {FruitGardener::factory('apple');FruitGardener::factory('grape');FruitGardener::factory('strawberry');//...} catch (BadFruitException $e) {//...}

這樣,農場一定會百果豐收啦!

3.使用簡單原廠模式設計一個“物件導向的”計算機

/** * 物件導向計算機 * 思路: * 1、物件導向的基本,封裝、繼承、多太 * 2、父類公用類 * 3、各種運算類 */ /** * 基類,運算類 * 只提供基本資料,不參與運算 */ class Operation {   // 第一個數 public $first_num = 0;   // 第二個數 public $second_num = 0;   /**  * 擷取結果,其他類覆蓋此方法  * @return double $result  */ public function getResult() {  $result = 0.00;     return $result; }} /** * 加法類 */class OperationAdd extends Operation { /**  * 覆蓋父類,實現加法演算法  */ public function getResult() {  $result = 0;  return $this->first_num + $this->second_num; }} /** * 減法類 * */class OperationSub extends Operation { /**  * 覆蓋父類,實現加法演算法  */ public function getResult() {  $result = 0;  return $this->first_num - $this->second_num; }} /** * 乘法類 * */class OperationMul extends Operation { /**  * 覆蓋父類,實現加法演算法  */ public function getResult() {  $result = 0;  return $this->first_num * $this->second_num; }} /** * 除類 * */class OperationDiv extends Operation { /**  * 覆蓋父類,實現加法演算法  */ public function getResult() {  $result = 0;     if ($this->second_num == 0) {   throw new Exception('除法操作第二個參數不能為零!');   return 0;  }     return $this->first_num / $this->second_num; }} /** * 工廠類 */class OperationFactory { /**  * 工廠函數  * @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());

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.