目錄
一、簡單工廠模式
(一)需求
(二)使用傳統的方法來完成
(三)傳統方法的優缺點
(四)基本介紹
(五)使用簡單工廠模式
二、工廠方法模式
(一)需求
(二)思路
(三)基本介紹
(四)工廠方法模式應用
三、抽象工廠模式
(一)基本介紹
(二)應用實例
一、簡單工廠模式
(一)需求
- 披薩的種類很多(比如 GreekPizz、CheesePizz 等)
- 披薩的制作有 prepare,bake, cut, box
- 完成披薩店訂購功能。
(二)使用傳統的方法來完成
1、類圖
2、代碼
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;}
}
?兩種pizza
public class GreekPizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubSystem.out.println(" 給希臘披薩 準備原材料 ");}}=========================================================
public class CheesePizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubSystem.out.println(" 給制作奶酪披薩 準備原材料 ");}
}
編寫OrderPizza去訂購需要的各種pizza
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);}
}
客戶端訂購pizza
//相當于一個客戶端,發出訂購
public class PizzaStore {public static void main(String[] args) {// TODO Auto-generated method stubnew OrderPizza();}}
(三)傳統方法的優缺點
(四)基本介紹
- 簡單工廠模式是屬于創建型模式,是工廠模式的一種。簡單工廠模式是由一個工廠對象決定創建出哪一種產品類的實例。簡單工廠模式是工廠模式家族中最簡單實用的模式
- 簡單工廠模式:定義了一個創建對象的類,由這個類來封裝實例化對象的行為(代碼)
- 在軟件開發中,當我們會用到大量的創建某種、某類或者某批對象時,就會使用到工廠模式
在簡單工廠模式中,主要涉及三個角色:抽象產品、具體產品和簡單工廠。
抽象產品:抽象產品可以是一個接口或抽象類,定義了產品通用的方法,有具體子類來實現
具體產品:具體產品是抽象產品的實現類,它實現了抽象產品中定義的方法
簡單工廠:包含創建對象的方法,隱藏了創建對象細節。
(五)使用簡單工廠模式
將對象的創建邏輯封裝在一個工廠類中,客戶端不需要知道具體的創建細節,只需要向工廠類請求所需對象即可。
簡單工廠類,封裝了創建對象的方法
//簡單工廠類,封裝了創建對象的細節
public class SimpleFactory {//根據orderType 返回對應的Pizza 對象public Pizza createPizza(String orderType) {Pizza pizza = null;System.out.println("使用簡單工廠模式");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("胡椒披薩");}return pizza;}}
orderpizza
public class OrderPizza {//定義一個簡單工廠對象SimpleFactory simpleFactory;Pizza pizza = null;//構造器public OrderPizza(SimpleFactory simpleFactory) {setFactory(simpleFactory);}public void setFactory(SimpleFactory simpleFactory) {String orderType = ""; //用戶輸入的this.simpleFactory = simpleFactory; //設置簡單工廠對象do {orderType = getType(); pizza = this.simpleFactory.createPizza(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 "";}}}
客戶端下單
//相當于一個客戶端,發出訂購
public class PizzaStore {public static void main(String[] args) {//使用簡單工廠模式new OrderPizza(new SimpleFactory());System.out.println("~~退出程序~~");}}
其實工廠模式還叫靜態工廠模式,也就是把創建對象的方法設置為靜態方法,那就不需要創建工廠對象了,直接用類名的方式調用工廠創建對象的方法即可。
//簡單工廠類,封裝了創建對象的細節
public class SimpleFactory {//簡單工廠模式 也叫 靜態工廠模式public static Pizza createPizza(String orderType) {Pizza pizza = null;System.out.println("使用簡單工廠模式2");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("胡椒披薩");}return pizza;}}
orderpizza
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 "";}}
}
總結:工廠封裝了對象的創建過程,降低了客戶端的復雜性,并且方便了產品類型的擴展和維護。
二、工廠方法模式
(一)需求
(二)思路
思路1

(三)基本介紹
在工廠方法模式中,主要涉及三個角色:抽象產品、具體產品、簡單工廠和具體工廠
抽象產品:抽象產品可以是一個接口或抽象類,定義了產品通用的方法,由具體子類來實現
具體產品:具體產品是抽象產品的實現類,它實現了抽象產品中定義的方法
抽象工廠:定義了創建產品的接口,包含一個或多個創建產品的抽象方法。
具體工廠:實現了抽象工廠接口,負責實例化具體產品。
(四)工廠方法模式應用
//將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;}
}
各種pizza
public class LDPepperPizza extends Pizza{@Overridepublic void prepare() {// TODO Auto-generated method stubsetName("倫敦的胡椒pizza");System.out.println(" 倫敦的胡椒pizza 準備原材料");}
}==============================================
public class LDCheesePizza extends Pizza{@Overridepublic void prepare() {// TODO Auto-generated method stubsetName("倫敦的奶酪pizza");System.out.println(" 倫敦的奶酪pizza 準備原材料");}
}==============================================
public class BJPepperPizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubsetName("北京的胡椒pizza");System.out.println(" 北京的胡椒pizza 準備原材料");}
}==============================================
public class BJCheesePizza extends Pizza {@Overridepublic void prepare() {// TODO Auto-generated method stubsetName("北京的奶酪pizza");System.out.println(" 北京的奶酪pizza 準備原材料");}}
orderpizza
public abstract class OrderPizza {//定義一個抽象方法,createPizza , 讓各個工廠子類自己實現abstract Pizza createPizza(String orderType);// 構造器public OrderPizza() {Pizza pizza = null;String orderType; // 訂購披薩的類型do {orderType = getType();pizza = createPizza(orderType); //抽象方法,由工廠子類完成//輸出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 "";}}
}
public class LDOrderPizza extends OrderPizza {@OverridePizza createPizza(String orderType) {Pizza pizza = null;if(orderType.equals("cheese")) {pizza = new LDCheesePizza();} else if (orderType.equals("pepper")) {pizza = new LDPepperPizza();}// TODO Auto-generated method stubreturn pizza;}}==============================================
public class BJOrderPizza extends OrderPizza {@OverridePizza createPizza(String orderType) {Pizza pizza = null;if(orderType.equals("cheese")) {pizza = new BJCheesePizza();} else if (orderType.equals("pepper")) {pizza = new BJPepperPizza();}// TODO Auto-generated method stubreturn pizza;}}
PizzaStore?
public class PizzaStore {public static void main(String[] args) {String loc = "bj";if (loc.equals("bj")) {//創建北京口味的各種Pizzanew BJOrderPizza();} else {//創建倫敦口味的各種Pizzanew LDOrderPizza();}// TODO Auto-generated method stub}}
總結:當需要新增pizza類型時,只需要實現具體的產品和具體的工廠即可,而無需修改客戶端的代碼。
三、抽象工廠模式
(一)基本介紹
- 抽象工廠模式:定義了一個interface用于創建相關或有依賴關系的對象簇,而無需指明具體的類
- 抽象工廠模式可以將簡單工廠模式和工廠方法模式進行整合。
- 從設計層面看,抽象工廠模式就是對簡單工廠模式的改進(或者稱為進一步的抽象)。
- 將工廠抽象成兩層,AbsFactory(抽象工廠) 和 具體實現的工廠子類。程序員可以根據創建對象類型使用對應的工廠子類。這樣將單個的簡單工廠類變成了工廠簇,更利于代碼的維護和擴展。
?類圖如下:
(二)應用實例
抽象工廠
//一個抽象工廠模式的抽象層(接口)
public interface AbsFactory {//讓下面的工廠子類來 具體實現public Pizza createPizza(String orderType);
}
?工廠實現類
//這是工廠子類
public class BJFactory implements AbsFactory {@Overridepublic Pizza createPizza(String orderType) {System.out.println("~使用的是抽象工廠模式~");// TODO Auto-generated method stubPizza pizza = null;if(orderType.equals("cheese")) {pizza = new BJCheesePizza();} else if (orderType.equals("pepper")){pizza = new BJPepperPizza();}return pizza;}}==================================================
public class LDFactory implements AbsFactory {@Overridepublic Pizza createPizza(String orderType) {System.out.println("~使用的是抽象工廠模式~");Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new LDCheesePizza();} else if (orderType.equals("pepper")) {pizza = new LDPepperPizza();}return pizza;}}
訂購披薩的類,通過聚合的方式設置工廠
public class OrderPizza {AbsFactory factory;// 構造器public OrderPizza(AbsFactory factory) {setFactory(factory);}private void setFactory(AbsFactory factory) {Pizza pizza = null;String orderType = ""; // 用戶輸入this.factory = factory;do {orderType = getType();// factory 可能是北京的工廠子類,也可能是倫敦的工廠子類pizza = factory.createPizza(orderType);if (pizza != null) { // 訂購okpizza.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 "";}}
}