一、引言 園子里有關設計模式的文章可以說數不勝數,之前也看過很多,但是其實理解都不深入,時間一長就忘了。最好是記錄下來,總結中加深印象,這裡也給剛開始進行開發的同學提個建議,不要因為自己寫的不好而不去寫,誰都是從菜鳥開始的,不斷的總結才能將知識消化成自己的。 現在開始今天的學習。 工廠模式是設計模式 ...
一、引言
園子里有關設計模式的文章可以說數不勝數,之前也看過很多,但是其實理解都不深入,時間一長就忘了。最好是記錄下來,總結中加深印象,這裡也給剛開始進行開發的同學提個建議,不要因為自己寫的不好而不去寫,誰都是從菜鳥開始的,不斷的總結才能將知識消化成自己的。
現在開始今天的學習。
工廠模式是設計模式中很重要的一個模式,其中有簡單工廠模式(並不能算一個模式),工廠模式,抽象工廠模式。
工廠模式,從名字可以看出,這是一個創建型的模式,是用來創建對象。我們從簡單工廠模式開始
二、簡單工廠模式
簡單工廠模式其實並不是一個設計模式,反而比較像一種變成習慣。為什麼會出現簡單工廠呢?
當使用"new"關鍵字創建一個對象時,此時該類就依賴與這個對象,也就是他們之間的耦合度高,當需求變化時,我們就不得不去修改此類的源碼。
當我們需要實例化一個類時,不知道實例化哪個類,那麼我們把這個變化封裝起來,用一個工廠來幫我們創建對象。
這裡我想用飯店的例子,先看類圖:
代碼實現:
//食物介面 public interface Food { //準備 void prepare(); //烹飪 void cook (); //打包 void box(); } //具體食物 魚 public class Fish implements Food { public void prepare() { System.out.println("洗魚"); } public void cook() { System.out.println("水煮魚"); } public void box() { System.out.println("大碗裝魚"); } } //具體食物類 肉 public class Meat implements Food { public void prepare() { System.out.println("切肉"); } public void cook() { System.out.println("紅燒肉"); } public void box() { System.out.println("裝肉"); } }
運行
//簡單工廠 public class SimpleFoodFactory { //靜態創建工廠方法 public static Food createFood(String type){ if(!type.isEmpty()) { switch (type){ case "FISH": return new Fish(); case "MEAT": return new Meat(); default: return null; } } return null; } }
運行結果:
簡單工廠模式很簡單,也很容易理解。它帶來了很多好處
1. 解決了客戶端直接依賴於具體對象的問題,客戶端可以消除直接創建對象的責任,而僅僅是消費產品。簡單工廠模式實現了對責任的分割
2.代碼復用,其他的客戶也可以用這個工廠來創建對象。
但是缺點也很明顯,擴展困難,一旦添加新菜單,工廠方法必須修改。工廠模式為我們解決這個問題。
三、工廠模式
先看一個結構圖:
從這個圖中可以看出,工廠方法中創建對象不再是在一個類中,每一個具體的產品類都有一個創建工廠,其唯一的職責就是創建對應的產品,這是兩個平行類層級
給出定義:定義了一個用於創建對象的介面,讓子類來決定要實例化哪一個類,工廠方法讓類把實例化延遲到其子類。
再改造下上面的例子
增加一個Creator介面,並創建兩個製造工廠FishCreator 和 MeatCreator
//工廠基類,創建食物基類 public interface Creator { Food CreateFoddFactory(); } //創建魚工廠 public class FishCreator implements Creator { public Food CreateFoddFactory() { return new Fish(); } } //創建肉工廠 public class MeatCreator implements Creator { public Food CreateFoddFactory() { return new Meat(); } }
運行
private static void factory() {
//創建工廠
Creator creator=new MeatCreator();
//創建食物
Food food = creator.CreateFoddFactory();
if(food!=null){
food.prepare();
food.cook();
food.box();
}
}
運行結果:
工廠方法通過將實例化延遲到子類解決了邏輯判斷問題,一旦需要擴展,只需要再添加一個子類及子類工廠即可,比如現在想要增加鴨子菜單,只需要增加一個鴨子類(Duck)及一個鴨子工廠(DuckCreator)即可。
下麵介紹更抽象的抽象工廠模式
四、抽象工廠模式
工廠模式中一個工廠只創建一個產品,但是在現實的大廠中一般都是創建一系列產品,成為產品族,比如我們上面的例子,我們餐館要開分店,然而每個地方的口味不一樣,有些地方喜歡辣的,有些則喜歡不辣的,我們可以設計生產辣產品的工廠及不辣產品的工廠,那麼這個時候就用到抽象工廠模式。
先看圖:
再結合之前的代碼,我們進行修改,先創建一個抽象食物工廠,再創建辣和不辣的工廠
//抽象工廠 public interface FoodFactory { //創建肉工廠 Meat createMeat(); //創建魚工廠 Fish createFish(); } //製造辣的工廠 public class HotFoodFactory implements FoodFactory { public Meat createMeat() { return new HotMeat(); } public Fish createFish() { return new HotFish(); } } //不辣的的工廠 public class NotHotFoodFactory implements FoodFactory { public Meat createMeat() { return new NotHotMeat(); } public Fish createFish() { return new NotHotFish(); } }
再增加辣的肉和不辣的肉
//辣的肉 public class HotMeat extends Meat { @Override public void cook() { System.out.println("紅燒辣的肉"); } } //不辣的肉 public class NotHotMeat extends Meat { @Override public void cook() { System.out.println("紅燒不辣的肉"); } } //辣的魚 public class HotFish extends Fish { @Override public void cook() { System.out.println("做特別辣的魚"); } } //不辣的魚 public class NotHotFish extends Fish { @Override public void cook() { System.out.println("做不辣的魚"); } }
運行
private static void abstractFactory() { //辣工廠創建辣產品 FoodFactory hotFoodFactoryoodFactory=new HotFoodFactory(); Fish hotfish = hotFoodFactoryoodFactory.createFish(); if(hotfish!=null){ hotfish.prepare(); hotfish.cook(); hotfish.box(); } System.out.println("-------------"); Meat hotMeat = hotFoodFactoryoodFactory.createMeat(); if(hotMeat!=null){ hotMeat.prepare(); hotMeat.cook(); hotMeat.box(); } }
運行結果:
抽象工廠模式將具體產品的創建延遲到具體工廠的子類中,這樣將對象的創建封裝起來,可以減少客戶端與具體產品類之間的依賴,從而使系統耦合度低,這樣更有利於後期的維護和擴展,這真是抽象工廠模式的優點所在,然後抽象模式同時也存在不足的地方。下麵就具體看下抽象工廠的缺點(缺點其實在前面的介紹中以已經涉及了):
抽象工廠模式很難支持新種類產品的變化。這是因為抽象工廠介面中已經確定了可以被創建的產品集合,如果需要添加新產品,此時就必須去修改抽象工廠的介面,這樣就涉及到抽象工廠類的以及所有子類的改變,這樣也就違背了“開發——封閉”原則。
知道了抽象工廠的優缺點之後,也就能很好地把握什麼情況下考慮使用抽象工廠模式了,下麵就具體看看使用抽象工廠模式的系統應該符合那幾個前提:
- 一個系統不要求依賴產品類實例如何被創建、組合和表達的表達,這點也是所有工廠模式應用的前提。
- 這個系統有多個系列產品,而系統中只消費其中某一系列產品
- 系統要求提供一個產品類的庫,所有產品以同樣的介面出現,客戶端不需要依賴具體實現。
一口學完了工廠模式,休息休息!