最近在啃設計模式,這篇文章是設計模式的第一篇,希望可以一直寫下去。
工廠模式和抽象工廠模式都屬於創建型模式,是用來創建對象的。程序中將創建對象的操作(例如各種new)抽離到單獨的接口中,由接口的子類來完成對象的創建工作,從而實現對象的創建與業務邏輯解耦的目的。這里所說的接口,既包括interface,也包括抽象類。
下面以“餃子”作為例子來講解這兩種模式的用法,餃子是我們要生產的產品,而工廠是我們生產餃子的工具。餃子餡兒的口味有很多,這里只舉出三種:韭菜、鮮肉、蘿卜。
1. 工廠模式
工廠模式的做法是,每個產品對應一個工廠,由工廠來負責對應產品的創建工作,工廠模式將生成產品的任務交給具體的子類來完成,做到了與具體產品類的解耦。
首先定義一個產品接口:
1 public interface Dumpling{ 2 String getFlavor(); //獲取餃子口味 3 }
接下來是三個具體口味的餃子:
1 public class FreshmeatDumpling implements Dumpling{ 2 String flavor = "鮮肉餡兒餃子"; 3 4 @Override 5 public String getFlavor(){ 6 return flavor; 7 } 8 } 9 10 public class LeekDumpling implements Dumpling{ 11 String flavor = "韭菜餡兒餃子"; 12 13 @Override 14 public String getFlavor(){ 15 return flavor; 16 } 17 } 18 19 public class RadishDumpling implements Dumpling{ 20 String flavor = "蘿卜餡兒餃子"; 21 22 @Override 23 public String getFlavor(){ 24 return flavor; 25 } 26 }
產品定義好之后,需要定義工廠來生產這些產品,也就是餃子。
先定義工廠接口:
1 public interface DumplingFactory{ 2 Dumpling createDumpling(); //生產餃子 3 }
接下來為每一種餃子定義一個對應的工廠:
1 public class FreshmeatDumplingFactory implements DumplingFactory{ 2 public Dumpling createDumpling(){ 3 return new FreshmeatDumpling(); //來一份鮮肉餡兒餃子 4 } 5 } 6 7 public class LeekDumplingFactory implements DumplingFactory{ 8 public Dumpling createDumpling(){ 9 return new LeekDumpling(); //來一份韭菜餡兒餃子 10 } 11 } 12 13 public class RedishRDumplingFactory implements DumplingFactory{ 14 public Dumpling createDumpling(){ 15 return new RedishDumpling(); //來一份蘿卜餡兒餃子 16 } 17 }
好了,所有的准備工作都做完了,現在就可以開心的點餐了^_^。
1 public static void main(String[] args){ 2 DumplingFactory factory = new LeekDumpingFactory(); 3 Dumpling dumpling = factory.createDumpling(); 4 System.out.println(dumpling.getFlavor()); //韭菜餡兒餃子 5 6 factory = new RedishDumplingFactory(); 7 dumpling = factory.createDumpling(); 8 System.out.println(dumpling.getFlavor()); //蘿卜餡兒餃子 9 }
2. 抽象工廠模式
抽象工廠模式的職責是創建一個產品簇,這往往意味着創建許多不同類型的產品,而工廠模式只負責創建單一產品。
對於餃子來說,除了餡兒之外,一般還會放一些配料,例如:蔥、姜、蒜等,那么此時我們就需要一個配料工廠專門生產這些配料了。這些配料屬於不同的產品系,它們合在一起構成餃子的配料,我們把類似配料的這樣的一系列產品稱為產品簇,顯然,工廠模式無法完成這個生產任務,這里就需要用到抽象工廠模式了。實際上,抽象工廠在生成每一類產品時,使用的還是工廠模式的原理。
首先,是定義配料接口以及具體的配料子類。
配料接口:
1 // 蔥 2 public interface Scallion{ 3 String getName(); 4 } 5 6 // 姜 7 public interface Ginger{ 8 String getName(); 9 } 10 11 // 蒜 12 public interface Garlic{ 13 String getName(); 14 }
具體配料:
1 public class GreenChineseonion implements Scallion{ 2 private String name = "大蔥"; 3 public String getName(){ 4 return name; 5 } 6 } 7 8 public class Shallot implements Scallion{ 9 private String name = "小蔥"; 10 public String getName(){ 11 return name; 12 } 13 } 14 15 public class RedGinger implements Ginger{ 16 private String name = "紫姜"; 17 public String getName(){ 18 return name; 19 } 20 } 21 22 public class YellowGinger implements Ginger{ 23 private String name = "黃姜"; 24 public String getName(){ 25 return name; 26 } 27 } 28 29 public class WhiteGarlic implements Garlic{ 30 private String name = "白皮蒜"; 31 public String getName(){ 32 return name; 33 } 34 } 35 36 public class PurpleGarlic implements Garlic{ 37 private String name = "紫皮蒜"; 38 public String getName(){ 39 return name; 40 } 41 }
接下來定義生產配料的工廠:
1 public interface IngredientsFactory{ 2 Scallion createScallion(); //生產蔥 3 Ginger createGinger(); //生產姜 4 Garlic createGarlic(); //生產蒜 5 }
然后定義具體配料工廠:
1 // 鮮肉餡兒餃子配料 2 public class FreshMeatDumplingIngredientsFactory implements IngredientsFactory{ 3 public Scallion createScallion(){ 4 return new Shallot(); 5 } 6 7 public Ginger createGinger(){ 8 return new RedGinger(); 9 } 10 11 public Garlic createGarlic(){ 12 return new WhiteGarlic(); 13 } 14 } 15 16 // 韭菜餡兒餃子配料 17 public class LeekDumplingIngredientsFactory implements IngredientsFactory{ 18 public Scallion createScallion(){ 19 return new Shallot(); 20 } 21 22 public Ginger createGinger(){ 23 return new RedGinger(); 24 } 25 26 public Garlic createGarlic(){ 27 return new PurpleGarlic(); 28 } 29 } 30 31 // 蘿卜餡兒餃子配料 32 public class RadishDumplingIngredientsFactory implements IngredientsFactory{ 33 public Scallion createScallion(){ 34 return new GreenChineseonion(); 35 } 36 37 public Ginger createGinger(){ 38 return new YellowGinger(); 39 } 40 41 public Garlic createGarlic(){ 42 return new Garlic 43 } 44 }
然后,就可以來點配料嘗嘗咸淡了。
1 public static void main(String[] args){ 2 IngredientsFactory ingredientsFactory = new RadishDumplingIngredientsFactory(); 3 System.out.println(ingredientsFactory.createScallion().getName); 4 System.out.println(ingredientsFactory.createGinger().getName); 5 System.out.println(ingredientsFactory.createGarlic().getName); 6 }
3. 簡單工廠
一般提到工廠模式的時候,都會提到簡單工廠,簡單工廠是把所有產品的創建任務放在一個類里面完成,一旦有新的產品,就需要修改簡單工廠里面的生產邏輯。
關於餃子,一個簡單工廠可能類似於:
1 public class SimpleDumplingFactory{ 2 public Dumpling createDumpling(String type){ 3 switch(type){ 4 case "freshMeat": 5 return new FreshMeatDumpling(); 6 break; 7 case "leek": 8 return new LeekDumpling(); 9 break; 10 case "radish": 11 return new RadishDumpling(); 12 break; 13 default: 14 return new FreshMeatDumpling(); 15 break; 16 } 17 } 18 }
4. 總結
簡單工廠是一個具體類,負責生產所有的產品,當有新的產品產生時,就需要修改生產產品的邏輯,不符合“對擴展開放,對修改關閉”的原則;工廠模式會為每個產品生成一個對應的工廠,當有新的產品出現時,只需要增加新的工廠即可;抽象工廠能夠生成一個產品簇,其中的每一個生產產品的方法都是利用了工廠模式。
5. 參考
<<Head First設計模式>>