工廠模式和抽象工廠模式


      最近在啃設計模式,這篇文章是設計模式的第一篇,希望可以一直寫下去。

      工廠模式和抽象工廠模式都屬於創建型模式,是用來創建對象的。程序中將創建對象的操作(例如各種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設計模式>>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM