定義一個用於建立對象的接口,讓子類決定實例化哪個類,工廠方法使一個類的實例化延遲到其子類。php
(工廠模式是咱們最經常使用的實例化對象模式了,是用工廠方法代替new操做的一種模式)html
工廠模式根據抽象程度的不一樣分爲三種:簡單工廠模式(也叫靜態工廠模式)、工廠方法模式、以及抽象工廠模式。java
不論是簡單工廠模式,工廠方法模式仍是抽象工廠模式,他們具備相似的特性,因此他們的適用場景也是相似的。編程
首先,做爲一種建立類模式,在任何須要生成複雜對象的地方,均可以使用工廠方法模式。有一點須要注意的地方就是複雜對象適合使用工廠模式,而簡單對象,特別是只須要經過new就能夠完成建立的對象,無需使用工廠模式。若是使用工廠模式,就須要引入一個工廠類,會增長系統的複雜度。架構
其次,工廠模式是一種典型的解耦模式,迪米特法則在工廠模式中表現的尤其明顯。假如調用者本身組裝產品須要增長依賴關係時,能夠考慮使用工廠模式。將會大大下降對象之間的耦合度。學習
再次,因爲工廠模式是依靠抽象架構的,它把實例化產品的任務交由實現類完成,擴展性比較好。也就是說,當須要系統有比較好的擴展性時,能夠考慮工廠模式,不一樣的產品用不一樣的實現工廠來組裝。ui
工廠方法模式有四個要素:spa
前文提到的簡單工廠模式跟工廠方法模式極爲類似,區別是:簡單工廠只有三個要素,他沒有工廠接口,而且獲得產品的方法通常是靜態的。由於沒有工廠接口,因此在工廠實現的擴展性方面稍弱,能夠算所工廠方法模式的簡化版,關於簡單工廠模式,在此一筆帶過。code
實現例子:htm
(java)
#場景是這樣的:汽車由發動機、輪、底盤組成,如今須要組裝一輛車交給調用者。假如不使用工廠模式,代碼以下: class Engine { public void getStyle(){ System.out.println("這是汽車的發動機"); } } class Underpan { public void getStyle(){ System.out.println("這是汽車的底盤"); } } class Wheel { public void getStyle(){ System.out.println("這是汽車的輪胎"); } } public class Client { public static void main(String[] args) { Engine engine = new Engine(); Underpan underpan = new Underpan(); Wheel wheel = new Wheel(); ICar car = new Car(underpan, wheel, engine); car.show(); } }
能夠看到,調用者爲了組裝汽車還須要另外實例化發動機、底盤和輪胎,而這些汽車的組件是與調用者無關的,嚴重違反了迪米特法則,耦合度過高。而且很是不利於擴展。另外,本例中發動機、底盤和輪胎仍是比較具體的,在實際應用中,可能這些產品的組件也都是抽象的,調用者根本不知道怎樣組裝產品。假如使用工廠方法的話,整個架構就顯得清晰了許多。
interface IFactory { public ICar createCar(); } class Factory implements IFactory { public ICar createCar() { Engine engine = new Engine(); Underpan underpan = new Underpan(); Wheel wheel = new Wheel(); ICar car = new Car(underpan, wheel, engine); return car; } } public class Client { public static void main(String[] args) { IFactory factory = new Factory(); ICar car = factory.createCar(); car.show(); } }
使用工廠方法後,調用端的耦合度大大下降了。而且對於工廠來講,是能夠擴展的,之後若是想組裝其餘的汽車,只須要再增長一個工廠類的實現就能夠。不管是靈活性仍是穩定性都獲得了極大的提升。
【每個模式都是針對必定問題的解決方案,工廠方法模式針對的是一個產品等級結構;而抽象工廠模式針對的是多個產品等級結構】
當每一個抽象產品都有多於一個的具體子類的時候,工廠角色怎麼知道實例化哪個子類呢?好比每一個抽象產品角色都有兩個具體產品。抽象工廠模式提供兩個具體工廠角色,分別對應於這兩個具體產品角色,每個具體工廠角色只負責某一個產品角色的實例化。每個具體工廠類只負責建立抽象產品的某一個具體子類的實例。【多對一】
產品族:
是指位於不一樣產品等級結構中,功能相關聯的產品組成的家族。通常是位於不一樣的等級結構中的相同位置上。顯然,每個產品族中含有產品的數目,與產品等級結構的數目是相等的,造成一個二維的座標系,水平座標是產品等級結構,縱座標是產品族。例如蔬菜、水果就是產品等級結構;產地北方、南方就是產品族
1 <?php 2 #抽象工廠模式 3 4 #產品等級結構(水果、蔬菜) 5 #產品水果 6 interface Fruit{} 7 #產品蔬菜 8 interface Vegetable{} 9 10 #產品族(北方、南方) 11 #一個產品族對應各個產品等級 12 #北方水果 13 class NorthFruit implements Fruit 14 { 15 //一列操做 16 } 17 #南方水果 18 class SouthFruit implements Fruit 19 { 20 //一列操做 21 } 22 #北方蔬菜 23 class NorthVegetable implements Vegetable 24 { 25 //一列操做 26 } 27 #南方蔬菜 28 class SouthVegetable implements Vegetable 29 { 30 //一列操做 31 } 32 33 #抽象工廠接口 34 #有多少個產品等級結構,接口就有多少個聲明方法 35 interface Factory 36 { 37 public function createFruit(); 38 public function createVegetable(); 39 } 40 #實現抽象接口,有多少個產品族就有多少個工廠類 41 #北方工廠類 42 class NorthFactory implements Factory 43 { 44 public function createFruit() 45 { 46 return new NorthFruit(); 47 } 48 49 public function createVegetable() 50 { 51 return new NorthVegetable(); 52 } 53 } 54 #南方工廠類 55 class SouthFactory implements Factory 56 { 57 public function createFruit() 58 { 59 return new SouthFruit(); 60 } 61 62 public function createVegetable() 63 { 64 return new SouthVegetable(); 65 } 66 } 67 68 #------------------------------# 69 #客戶端 70 #想要哪一個對象就找工廠 71 $northFactory=new NorthFactory(); 72 $a=$northFactory->createFruit(); #獲取北方水果對象 73 74 ?>
優勢:
缺點:
(以上是本身的一些看法,如有不足或者錯誤的地方請各位指出)
做者:那一葉隨風 http://www.cnblogs.com/phpstudy2015-6/
原文地址: https://www.cnblogs.com/phpstudy2015-6/p/6732784.html
聲明:本博客文章爲原創,只表明本人在工做學習中某一時間內總結的觀點或結論。轉載時請在文章頁面明顯位置給出原文連接