原文地址:PHP設計模式(八):工廠模式php
在PHP設計模式(七):設計模式分類中咱們提到過建立設計模式(Creation patterns),建立設計模式專一於設計對象(Object)和實例(Instance)的建立過程。
建立設計模式包括下面五種設計模式:程序員
抽象工廠設計模式(Abstract Factory)設計模式
生成器模式(Builder)架構
工廠設計模式(Factory Method)函數
原型設計模式(Prototype Method)ui
單例設計模式(Singleton)this
當程序逐漸擴展的時候,須要更多的新對象,新對象的建立不該該依賴於建立者,換句話說,新對象的建立過程,不該該依賴調用建立函數的對象。爲了減小冗餘,增長拓展性,工廠模式就是一種建立新對象時使用的設計模式。設計
工廠模式,也是五種設計模式中惟一的類的設計模式(Class patterns),即在類中就能實現的設計模式。
聽起來挺抽象?對比原型設計模式,這是一種對象設計模式(Object patterns),經過對象的__clone()方法來實現的設計模式。
在工廠模式中,新建立的對象/產品並不依賴於生產它的對象/工廠,新對象和調用者之間是低耦合狀態。一般調用者和工廠交互,由工廠來生成新對象,新對象只和工廠有關。code
簡單來講,當需求對類的個數不明確的時候,可使用工廠模式,如:
你須要建立一個在線博物館,但你並不確切的知道究竟有多少文物,你不可能無限的增長新的文物類,同時對於損毀的文物,你不可能無限的去清理這些類。
反過來講,若是你確切的知道類的總量,那麼你就沒有必要使用工程模式,直接經過繼承的方式就能實現好的設計。對象
仍是使用咱們慣用的鯨魚和鯉魚的例子,如今咱們想實現一個海洋館,目前咱們並不肯定究竟有多少海洋生物。
先是一個抽象的工廠類:
<?php abstract class Factory { protected abstract function create(); public function factoryStart() { return $this->create(); } } ?>
而後是兩個工廠:鯨魚工廠和鯉魚工廠
<?php class WhaleFactory extends Factory { protected function create() { $whale = new Whale(); return $whale->create(); } } class CarpFactory extends Factory { protected function create() { $carp = new Carp(); return $carp->create(); } } ?>
而後是抽象的動物接口:
<?php interface Animal { public function create(); } ?>
而後是具體的動物類:鯨魚類和鯉魚類
<?php class Whale implements Animal { private $name; public function create() { $this->name = "Whale"; return $this->name . " is created.\n"; } } class Carp implements Animal { private $name; public function create() { $this->name = "Carp"; return $this->name . " is created.\n"; } } ?>
下面給出使用工廠建立鯨魚和鯉魚的代碼:
<?php $whaleFactory = new WhaleFactory(); echo $whaleFactory->factoryStart(); $carpFactory = new CarpFactory(); echo $carpFactory->factoryStart(); ?>
運行一下:
Whale is created. Carp is created.
到這裏你是否是以爲,其實直接生成兩個類就好了,何須搞這麼複雜?彆着急,好戲在後面。
因爲Interface的限制,修改類的方法被限定在了create()方法中,所以能夠避免偷懶的程序員新增長的不合理函數。
簡單修改一下:
<?php class Whale implements Animal { private $name; public function create() { $this->name = "Whale"; return $this->name . " is created. Whale eats fish.\n"; } } class Carp implements Animal { private $name; public function create() { $this->name = "Carp"; return $this->name . " is created. Carp eats moss.\n"; } } ?>
因爲對象是由工廠造出來的,外部不可能直接調用或者修改類的實現,類的修改被限定在了類的對外接口上。這樣的架構易於擴展。
工廠模式的靈活,在於能夠只擁有一個工廠,卻能生產多個類/產品。
修改咱們的抽象工廠,給create()方法增長animal接口:
<?php abstract class Factory { protected abstract function create(Animal $animal); public function factoryStart($animal) { return $this->create($animal); } } ?>
而後合併以前的鯨魚工廠和鯉魚工廠:
<?php class AnimalFactory extends Factory { protected function create(Animal $animal) { return $animal->create(); } } ?>
修改使用工廠建立鯨魚和鯉魚的代碼:
<?php $animalFactory = new AnimalFactory(); echo $animalFactory->factoryStart(new Whale()); echo $animalFactory->factoryStart(new Carp()); ?>
運行一下:
Whale is created. Whale eats fish. Carp is created. Carp eats moss.
鯨魚類和鯉魚類源源不斷的從一個工廠中被建立出來了。經過這種設計模式,類的建立過程統一經過一個接口來實現,接口外部並不須要關心類是如何被建立出來的,而接口內部實現也獲得了很好的拓展性。
本文介紹了工廠設計模式,使用這種設計模式,可讓你經過一個或多個工廠的接口,建立無數新類,調用任意類的方法。因爲接口嚴格定義了新類/產品的形態,所以在維護和拓展的時候,能夠省去很多力氣。