2018年8月22日19:34:48
html
吾欲娶卿,必問卿之父母,謂之父母之命。java
工廠方法模式(Factory Method),定義一個用於建立對象的接口,讓子類決定實例化哪個類。工廠方法使一個類的實例化延遲到其子類。 ——《設計模式:可複用面向對象軟件的基礎》git
工廠方法模式在簡單工廠模式的基礎上,將判斷邏輯的選擇權上交給客戶端,讓客戶端決定使用哪一個具體工廠類。這算是工廠方法相比與簡單工廠模式的缺點吧,這樣的話,你就要事先知道有什麼具體工廠類。相對於直白的new對象,不須要記住具體產品類,服務端隱藏了具體產品類的建立細節,在具體工廠類中不必定就是建立具體產品類,也能夠作一些其餘事情,符合面向對象的封裝性。github
簡單工廠模式加產品,須要修改內部判斷邏輯,這是違反設計模式六大模式中的開閉原則(挖坑),就是對擴展是開放的,對修改是關閉的。工廠方法模式加產品,只需增長相對應的具體工廠對象便可,符合開閉原則,這是工廠方法模式優勢之一。我的觀點:工廠方法模式適合那種常常更替(即增長和刪除)具體產品對象的場景,正好利用了這個優勢。如服裝換季,你是一個設計師,換季了新的產品上架,加上新產品,老闆選擇新工廠,銷售商家只須要從工廠獲取新產品便可,舊產品下架,和舊工廠合同到期,就這樣。設計模式
將簡單工廠模式的工廠角色內部邏輯判斷上交給客戶端後,分別封裝建立對象細節到具體工廠類,具體工廠類都繼承於一個共同的接口。簡單工廠模式可查看:簡單工廠模式。ide
工廠方法模式有如下四種角色:測試
代碼示例依然用的是加減乘除運算操做,跟簡單工廠模式同樣,只是將工廠類SimpleFactory拆分爲抽象工廠類和具體工廠類。簡單工廠模式可查看:簡單工廠模式。設計
類依賴關係圖:
3d
抽象工廠角色(IOperationFactory.java):code
public interface IOperationFactory { public IOperation createOperation(); }
抽象出來的具體工廠對象公共接口。
具體工廠角色(AddOperationFactoryImpl.java、SubOperationFactoryImpl.java、MulOperationFactoryImpl.java、DivOperationFactoryImpl.java):
// 加法工廠 public class AddOperationFactoryImpl implements IOperationFactory { @Override public IOperation createOperation() { return new AddOperationImpl(); } } // 減法工廠 public class SubOperationFactoryImpl implements IOperationFactory { @Override public IOperation createOperation() { return new SubOperationImpl(); } } // 乘法工廠 public class MulOperationFactoryImpl implements IOperationFactory { @Override public IOperation createOperation() { return new MulOperationImpl(); } } // 除法工廠 public class DivOperationFactoryImpl implements IOperationFactory { @Override public IOperation createOperation() { return new DivOperationImpl(); } }
每一個具體工廠對象對應一個具體產品對象。
抽象產品角色(IProduct.java):
public interface IOperation { public int getResult(int a, int b); }
具體產品角色(AddOperationImpl.java、SubOperationImpl.java、MulOperationImpl.java、DivOperationImpl.java):
// 加法實現類 public class AddOperationImpl implements IOperation{ @Override public int getResult(int a, int b) { return a + b; } } // 減法實現類 public class SubOperationImpl implements IOperation { @Override public int getResult(int a, int b) { return a - b; } } // 乘法實現類 public class MulOperationImpl implements IOperation { @Override public int getResult(int a, int b) { return a * b; } } // 除法實現類 public class DivOperationImpl implements IOperation { @Override public int getResult(int a, int b) { return a / b; } }
測試類(FactoryMethodTest.java):
public class FactoryMethodTest { public static void main(String[] args) { int a = 999, b = 888; // 加 // 建立具體工廠 IOperationFactory operationFactory = new AddOperationFactoryImpl(); // 建立具體產品 IOperation operation = operationFactory.createOperation(); // 調用具體產品的功能 int result = operation.getResult(a, b); // 1887 System.out.println(result); // 減 operationFactory = new SubOperationFactoryImpl(); operation = operationFactory.createOperation(); result = operation.getResult(a, b); // 111 System.out.println(result); // 乘 operationFactory = new MulOperationFactoryImpl(); operation = operationFactory.createOperation(); result = operation.getResult(a, b); // 887112 System.out.println(result); // 除 operationFactory = new DivOperationFactoryImpl(); operation = operationFactory.createOperation(); result = operation.getResult(a, b); // 1 System.out.println(result); } }
客戶端要判斷使用什麼具體工廠對象,從而實例化所需的具體產品對象。
(連接在文末參考處)
一、在工廠方法模式中,工廠方法用來建立客戶所須要的產品,同時還向客戶隱藏了哪一種具體產品類將被實例化這一細節,用戶只須要關心所需產品對應的工廠,無須關心建立細節,甚至無須知道具體產品類的類名。
二、基於工廠角色和產品角色的多態性設計是工廠方法模式的關鍵。它可以使工廠能夠自主肯定建立何種產品對象,而如何建立這個對象的細節則徹底封裝在具體工廠內部。工廠方法模式之因此又被稱爲多態工廠模式,是由於全部的具體工廠類都具備同一抽象父類。
三、使用工廠方法模式的另外一個優勢是在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的接口,無須修改客戶端,也無須修改其餘的具體工廠和具體產品,而只要添加一個具體工廠和具體產品就能夠了。這樣,系統的可擴展性也就變得很是好,徹底符合「開閉原則」。
一、在添加新產品時,須要編寫新的具體產品類,並且還要提供與之對應的具體工廠類,系統中類的個數將成對增長,在必定程度上增長了系統的複雜度,有更多的類須要編譯和運行,會給系統帶來一些額外的開銷。
二、因爲考慮到系統的可擴展性,須要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增長了系統的抽象性和理解難度,且在實現時可能須要用到DOM、反射等技術,增長了系統的實現難度。
工廠方法模式是簡單工廠模式的進一步抽象和推廣。
因爲使用了面向對象的多態性,工廠方法模式保持了簡單工廠模式的優勢,並且克服了它的缺點。
全部代碼可見於Github.Mingmingcome
完
參考: