定義:定義一個創建產品對象的工廠介面,將實際創建工作推遲到子類當中。核心工廠類不再負責產品的創建,這樣核心類成為一個抽象工廠角色,僅負責具體工廠子類必須實現的介面,這樣進一步抽象化的好處是使得工廠方法模式可以使系統在不修改具體工廠角色的情況下引進新的產品。 工廠方法模式在簡單工廠模式的基礎上抽象出了 ...
定義:定義一個創建產品對象的工廠介面,將實際創建工作推遲到子類當中。核心工廠類不再負責產品的創建,這樣核心類成為一個抽象工廠角色,僅負責具體工廠子類必須實現的介面,這樣進一步抽象化的好處是使得工廠方法模式可以使系統在不修改具體工廠角色的情況下引進新的產品。
工廠方法模式在簡單工廠模式的基礎上抽象出了工廠介面,將創建產品的工作推遲到實現工廠介面的具體工廠類中,當我們需要增加一個產品的時候,簡單工廠模式下需要對工廠類進行修改,這就違反了對修改封閉的原則,而工廠方法模式就彌補了這個不足之處,接下來我們來看下工廠方法模式的結構類圖
主要可以分為四類:其一是產品介面;其一是具體的產品類;其一是工廠介面,其中包含一個創建創建產品的介面;還有就是用來生產具體產品的具體工廠類,當我們需要增加一個產品的時候,只需要增加一個具體的產品類和具體的工廠類,不會對原來的代碼有任何的修改。接下來看下具體的代碼實現
產品介面
public interface Product { void use(); }
兩個具體的產品類
public class ConcreteProductA implements Product { @Override public void use() { System.out.println("使用產品A"); } }
public class ConcreteProductB implements Product { @Override public void use() { System.out.println("使用產品B"); } }
工廠介面
public interface Factory { Product createProduct(); }
具體的工廠類
public class ConcreteFactoryA implements Factory { @Override public Product createProduct() { return new ConcreteProductA(); } }
public class ConcreteFactoryB implements Factory { @Override public Product createProduct() { return new ConcreteProductB(); } }
測試類的調用和輸出結果
Factory factoryA = new ConcreteFactoryA(); Product productA = factoryA.createProduct(); productA.use(); Factory factoryB = new ConcreteFactoryB(); Product productB = factoryB.createProduct(); productB.use();
相比與簡單工廠模式,我們不需要在工廠類中判斷要創建哪種的產品類,但是卻將判斷的邏輯移到了測試客戶端代碼中,客戶端要知道該創建哪種工廠對象才能創建出需要的產品對象。上述代碼並沒有邏輯判斷的代碼,我們通過將簡單工廠模式中的簡單計算器的例子使用工廠方法模式來實現,就能清晰的看到其中邏輯判斷的轉移,具體的實現代碼如下,其中產品介面和具體的產品類與簡單工廠的一致就不貼出來了
運算工廠介面
public interface OperationFactory { AbstractOperation createOperation(); }
具體的運算工廠類(只貼出來一個,其他類似)
public class OperationAddFactory implements OperationFactory { @Override public AbstractOperation createOperation() { return new OperationAdd(); } }
最後就是擁有條件判斷的客戶端代碼和輸出(隨用戶的輸入變化而變化)
Scanner scanner = new Scanner(System.in); System.out.println("請輸入數字A:"); double numberA = scanner.nextDouble(); System.out.println("請輸入運算符號:"); String operationType = scanner.next(); System.out.println("請輸入數字A:"); double numberB = scanner.nextDouble(); OperationFactory of; switch (operationType) { case "+": of = new OperationAddFactory(); break; case "-": of = new OperationSubFactory(); break; case "*": of = new OperationMulFactory(); break; case "/": of = new OperationDivFactory(); break; default: throw new RuntimeException("輸入的運算符號錯誤:" + operationType); } AbstractOperation operation = of.createOperation(); operation.setNumberA(numberA); operation.setNumberB(numberB); System.out.println(operation.getResult());
以上就是整個功能的實現代碼,可以通過點擊以下鏈接獲取代碼和類圖