一文必懂-工厂模式
工廠模式
- 工廠模式
- 傳統方式創建一類對象
- 優缺點
- 簡單工廠模式
- 工廠方法模式
- 應用場景與優點
- 抽象方法模式
- 應用場景
- 優點
- JDK源碼中的應用:
- 工廠方法與抽象工廠的區別
今天也是干的一天
工廠模式
工廠模式分為簡單工廠、工廠方法與抽象工廠模式;
傳統方式創建一類對象
Pizza.java
package com.yxj.factory.simplefactory.pizzastore.pizza;//將Pizza 類做成抽象 public abstract class Pizza {protected String name; //名字//準備原材料, 不同的披薩不一樣,因此,我們做成抽象方法public abstract void prepare();public void bake() {System.out.println(name + " baking;");}public void cut() {System.out.println(name + " cutting;");}//打包public void box() {System.out.println(name + " boxing;");}public void setName(String name) {this.name = name;} }CheesePizza.java
package com.yxj.factory.simplefactory.pizzastore.pizza;public class CheesePizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubSystem.out.println(" 給制作奶酪披薩 準備原材料 ");}}GreekPizza.java
package com.yxj.factory.simplefactory.pizzastore.pizza;public class GreekPizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubSystem.out.println(" 給希臘披薩 準備原材料 ");}}OrderPizza.java
public class OrderPizza {//構造器public OrderPizza() {Pizza pizza = null;String orderType; // 訂購披薩的類型do {orderType = getType();if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName(" 希臘披薩 ");} else if (orderType.equals("cheese")) {pizza = new CheesePizza();pizza.setName(" 奶酪披薩 ");} else if (orderType.equals("pepper")) {pizza = new PepperPizza();pizza.setName("胡椒披薩");} else {break;}//輸出pizza 制作過程pizza.prepare();pizza.bake();pizza.cut();pizza.box();} while (true);}// 寫一個方法,可以獲取客戶希望訂購的披薩種類private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 種類:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}}PepperPizza.java
package com.yxj.factory.simplefactory.pizzastore.pizza;public class PepperPizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubSystem.out.println(" 給胡椒披薩準備原材料 ");}}PizzaStore.java
package com.yxj.factory.simplefactory.pizzastore.order;//相當于一個客戶端,發出訂購 public class PizzaStore {public static void main(String[] args) {// TODO Auto-generated method stubnew OrderPizza();}}優缺點
- 簡單、容易理解
- 違反了OCP原則,即對擴展開放,對修改關閉。即當我們給類增加新功能的時候,盡量不修改已經寫好的代碼,或者盡可能少修改代碼。
- 比如我們這時要新增加一個Pizza的種類(CheesePizza披薩),我們需要做如下修改.
- 也許有人會說,不就一個地方修改了代碼嗎?但是在工作中,可能在其他的地方也有創建Pizza代碼,意味著其他的地方也要修改,而創建Pizza代碼的地方,有很多處的情況下,就麻煩了。
- 思路:把創建Pizza對象封裝到一個類中,這樣我們有新的Pizza種類時,只需要修改該
類就可,其它有創建到Pizza對象的代碼就不需要修改了.-> 簡單工廠模式
簡單工廠模式
簡單工廠模式是屬于創建型模式、是工廠模式的一種。簡單工廠模式就是由一個對象(對應一個SimpleFactory類)決定創建出哪一產品類的實例。
核心類SimpleFactory
OrderPizza2.java
public class OrderPizza2 {Pizza pizza = null;String orderType = "";// 構造器public OrderPizza2() {do {orderType = getType();pizza = SimpleFactory.createPizza2(orderType);// 輸出pizzaif (pizza != null) { // 訂購成功pizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println(" 訂購披薩失敗 ");break;}} while (true);}// 寫一個方法,可以獲取客戶希望訂購的披薩種類private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 種類:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}} }- 核心就是SimpleFactory的實現,使用該類負責實例的創建,符合OCP開閉原則;
工廠方法模式
定義一個用于創建對象的接口,讓子類決定實例化哪一個類。Factory Method使得一個類的實例化延遲到子類;
package com.tuling.designpattern.factorymethod;/*** @author 玄霄* @Slogan 致敬大師,致敬未來的你*/ public class FactoryMethodTest {public static void main(String[] args) {Application application= new ConcreteProductB();Product product=application.getObject();product.method1();} }interface Product{void method1(); }class ProductA implements Product{@Overridepublic void method1() {System.out.println( "ProductA.method1 executed." );} }class ProductB implements Product{@Overridepublic void method1() {System.out.println( "ProductB.method1 executed." );} }// 簡單工廠 class SimpleFactory{public static Product createProduct(String type){if ("A".equals( type )){return new ProductA();}return null;} }// 變化 , 共同點 abstract class Application {// 工廠方法public abstract Product createProduct();public Product getObject() {Product product=createProduct();// ......這是公共不變的部分代碼return product;} }class ConcreteProductA extends Application{@Overridepublic Product createProduct() {ProductA productA=new ProductA();return productA;} }class ConcreteProductB extends Application{@Overridepublic Product createProduct() {ProductB productB=new ProductB();return productB;} }應用場景與優點
- 當你不知道改使用對象的確切類型的時候
- 當你希望為庫或框架提供擴展其內部組件的方法時
優點:
- 將具體產品和創建者解耦
- 符合單一職責原則
- 符合開閉原則
抽象方法模式
提供一個創建一系列相關或互相依賴對象的接口,而無需指定他們的具體的類
- AbstractProductA:創建A類產品所實現的接口,該接口包含了A類產品中共有的方法;
- ProductA1,ProductA2:A類的具體產品;
- AbstractProductB:創建B類產品所實現的接口,該接口包含了B類產品中共有的方法;
- ProductB1,ProductB2:B類的具體產品
- AbstracyFactory:包含了創建的A類、B類產品的接口方法;
- ConcreteFactory1: 創建 “1”系列的產品,即ProductA1,ProductB1;
- ConcreteFactory2: 創建 “2”系列的產品,即ProductA2,ProductB2;
應用場景
- 程序需要處理不同系列的相關產品,但是您不希望它依賴于這些產品的具體類時
- 可以使用抽象工廠
優點
JDK源碼中的應用:
java.sql.Connection java.sql.Driver工廠方法與抽象工廠的區別
當抽象工廠接口方法只有一個時,就變成了工廠方法模式;
千軍萬馬一將在,探囊取物有何難
總結
- 上一篇: 别人家的键盘--机械键盘
- 下一篇: C语言画心