2018年8月22日19:34:48
Factory 方法模式定義
吾欲娶卿,必問卿之父母,謂之父母之命。
Factory 方法模式(Factory Method),定義一個用於建立對象的介面,讓子類決定執行個體化哪一個類。Factory 方法使一個類的執行個體化延遲到其子類。 ——《設計模式:可複用物件導向軟體的基礎》
使用情境
Factory 方法模式在簡單原廠模式的基礎上,將判斷邏輯的選擇權上交給用戶端,讓用戶端決定使用哪個具體工廠類。這算是Factory 方法相比與簡單原廠模式的缺點吧,這樣的話,你就要事Crowdsourced Security Testing道有什麼具體工廠類。相對於直白的new對象,不需要記住具體產品類,服務端隱藏了具體產品類的建立細節,在具體工廠類中不一定就是建立具體產品類,也可以做一些其他事情,符合物件導向的封裝性。
簡單原廠模式加產品,需要修改內部判斷邏輯,這是違反設計模式六大模式中的開閉原則(挖坑),就是對擴充是開放的,對修改是關閉的。Factory 方法模式加產品,只需增加相對應的具體工廠對象即可,符合開閉原則,這是Factory 方法模式優點之一。個人觀點:Factory 方法模式適合那種經常更替(即增加和刪除)具體產品對象的情境,正好利用了這個優點。如服裝換季,你是一個設計師,換季了新的產品上架,加上新產品,老闆選擇新工廠,銷售商家只需要從工廠擷取新產品即可,舊產品下架,和舊工廠合約到期,就這樣。
角色
將簡單原廠模式的工廠角色內部邏輯判斷上交給用戶端後,分別封裝建立對象細節到具體工廠類,具體工廠類都繼承於一個共同的介面。簡單原廠模式可查看:簡單原廠模式。
Factory 方法模式有以下四種角色:
- 抽象工廠角色(IFactory):具體工廠公用介面,定義Factory 方法返回產品
- 具體工廠角色(ConcreteFactoryImpl):繼承工廠工廠公用介面,實現Factory 方法,運行期返回具體產品執行個體
- 抽象產品角色(IProduct)
- 具體產品角色(ConcreteProductImpl)
圖示
程式碼範例
程式碼範例依然用的是加減乘除運算操作,跟簡單原廠模式一樣,只是將工廠類SimpleFactory拆分為抽象工廠類和具體工廠類。簡單原廠模式可查看:簡單原廠模式。
類依賴關係圖:
抽象工廠角色(IOperationFactory.java):
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); } }
用戶端要判斷使用什麼具體工廠對象,從而執行個體化所需的具體產品對象。
優點(小抄)
(連結在文末參考處)
1、在Factory 方法模式中,Factory 方法用來建立客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被執行個體化這一細節,使用者只需要關心所需產品對應的工廠,無須關心建立細節,甚至無須知道具體產品類的類名。
2、基於工廠角色和產品角色的多態性設計是Factory 方法模式的關鍵。它能夠使工廠可以自主確定建立何種產品對象,而如何建立這個對象的細節則完全封裝在具體工廠內部。Factory 方法模式之所以又被稱為多態原廠模式,是因為所有的具體工廠類都具有同一抽象父類。
3、使用Factory 方法模式的另一個優點是在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的介面,無須修改用戶端,也無須修改其他的具體工廠和具體產品,而只要添加一個具體工廠和具體產品就可以了。這樣,系統的可擴充性也就變得非常好,完全符合“開閉原則”。
缺點(小抄)
1、在添加新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數將成對增加,在一定程度上增加了系統的複雜度,有更多的類需要編譯和運行,會給系統帶來一些額外的開銷。
2、由於考慮到系統的可擴充性,需要引入抽象層,在用戶端代碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度,且在實現時可能需要用到DOM、反射等技術,增加了系統的實現難度。
總結
Factory 方法模式是簡單原廠模式的進一步抽象和推廣。
由於使用了物件導向的多態性,Factory 方法模式保持了簡單原廠模式的優點,而且克服了它的缺點。
所有代碼可見於Github.Mingmingcome
完
參考:
Factory 方法模式(Factory Method Pattern)