自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

工廠設(shè)計模式案例詳解,不服來辯!

開發(fā) 前端
工廠模式(Factory Pattern)是 Java 中最常用的設(shè)計模式之一,今天我們一起來徹底解析一下它。

[[415212]]

本文轉(zhuǎn)載自微信公眾號「Java極客技術(shù)」,作者鴨血粉絲 。轉(zhuǎn)載本文請聯(lián)系Java極客技術(shù)公眾號。

工廠模式(Factory Pattern)是 Java 中最常用的設(shè)計模式之一,今天我們一起來徹底解析一下它。

一、介紹

從名稱上,顧名思義就是創(chuàng)建產(chǎn)品,按類別分為簡單工廠模式、工廠方法模式、抽象工廠模式,主要功能都是幫助我們把對象的實例化操作單獨抽取出來,優(yōu)化系統(tǒng)架構(gòu),增強(qiáng)系統(tǒng)的擴(kuò)展性。

下面,我們一起來看看各個模式的使用方式。

二、簡單工廠模式

簡單工廠模式,對象創(chuàng)建管理方式最為簡單,因為其僅僅簡單的對不同類對象的創(chuàng)建進(jìn)行了一層薄薄的封裝。該模式通過向工廠傳遞類型來指定要創(chuàng)建的對象。

  • 創(chuàng)建一個接口
  1. public interface Product { 
  2.    void operation1(); 
  3.    void operation2(); 
  • 創(chuàng)建實現(xiàn)接口的實體類
  1. public class ConcreateProductA implements Product{ 
  2.  
  3.    @Override 
  4.    public void operation1() { 
  5.       System.out.println("產(chǎn)品A,執(zhí)行任務(wù)1"); 
  6.    } 
  7.     
  8.    @Override 
  9.    public void operation2() { 
  10.       System.out.println("產(chǎn)品A,執(zhí)行任務(wù)2"); 
  11.    } 
  1. public class ConcreateProductB implements Product{ 
  2.  
  3.    @Override 
  4.    public void operation1() { 
  5.       System.out.println("產(chǎn)品B,執(zhí)行任務(wù)1"); 
  6.    } 
  7.     
  8.    @Override 
  9.    public void operation2() { 
  10.       System.out.println("產(chǎn)品B,執(zhí)行任務(wù)2"); 
  11.    } 
  • 創(chuàng)建一個工廠,生成基于給定信息的實體類的對象
  1. public class SimpleFactory { 
  2.      
  3.    //使用 create 方法獲取形狀類型的對象 
  4.    public Product create(String productType){ 
  5.       if(productType == null){ 
  6.          return null
  7.       } 
  8.       if(productType.equalsIgnoreCase("productA")){ 
  9.          return new ConcreateProductA(); 
  10.       } 
  11.       if(productType.equalsIgnoreCase("productB")){ 
  12.          return new ConcreateProductB(); 
  13.       } 
  14.       return null
  15.    } 
  • 編寫客戶端測試類,使用該工廠,通過傳遞類型信息來獲取實體類的對象
  1. public class FactoryPatternDemo { 
  2.   
  3.    public static void main(String[] args) { 
  4.       SimpleFactory simpleFactory = new SimpleFactory(); 
  5.        
  6.       //獲取 productA 的對象 
  7.       Product productA = simpleFactory.create("productA"); 
  8.   
  9.       //調(diào)用 productA 的 operation1、operation2 方法 
  10.       productA.operation1(); 
  11.       productA.operation2(); 
  12.   
  13.       //獲取 productB 的對象 
  14.       Product productB = simpleFactory.create("productB"); 
  15.   
  16.       //調(diào)用 productB 的 operation1、operation2 方法 
  17.       productB.operation1(); 
  18.       productB.operation2(); 
  19.    } 
  • 執(zhí)行程序,輸出結(jié)果:
  1. 產(chǎn)品A,執(zhí)行任務(wù)1 
  2. 產(chǎn)品A,執(zhí)行任務(wù)2 
  3. 產(chǎn)品B,執(zhí)行任務(wù)1 
  4. 產(chǎn)品B,執(zhí)行任務(wù)2 

當(dāng)然,還可以將創(chuàng)建對象方式進(jìn)行改進(jìn),將SimpleFactory類創(chuàng)建對象的方式改成如下方式:

  1. public class SimpleFactory { 
  2.      
  3.    //反射機(jī)制獲取實體類 
  4.    public <T> T createByClazzName(Class<? extends T> clazz){ 
  5.   T obj = null
  6.   try { 
  7.    obj = (T) Class.forName(clazz.getName()).newInstance(); 
  8.   } catch (Exception e) { 
  9.    // TODO Auto-generated catch block 
  10.    e.printStackTrace(); 
  11.   } 
  12.   return obj; 
  13.  } 

這樣做的好處是,當(dāng)有新的產(chǎn)品加入時,不用修改工廠類,在調(diào)用的時候,采用如下方式即可獲取對象!

  1. Product product = new SimpleFactory().create("類名.class"); 

三、工廠方法模式

和簡單工廠模式中工廠負(fù)責(zé)生產(chǎn)所有產(chǎn)品相比,工廠方法模式將生成具體產(chǎn)品的任務(wù)分發(fā)給具體的產(chǎn)品工廠。

  • 創(chuàng)建一個工廠接口
  1. public interface FactoryProduct { 
  2.    Product create(); 
  • 創(chuàng)建實現(xiàn)接口的實體類
  1. public class ConcreateFactoryA implements FactoryProduct{ 
  2.  
  3.    @Override 
  4.    public Product create() { 
  5.       return new ConcreateProductA(); 
  6.    } 
  1. public class ConcreateFactoryB implements FactoryProduct{ 
  2.  
  3.    @Override 
  4.    public Product create() { 
  5.       return new ConcreateProductB(); 
  6.    } 
  • 編寫客戶端測試類,使用該工廠,通過傳遞類型信息來獲取實體類的對象
  1. public class FactoryPatternDemo { 
  2.  
  3.    public static void main(String[] args) { 
  4.  
  5.       //獲取 productA 的對象 
  6.       Product productA = new ConcreateFactoryA().create(); 
  7.  
  8.       //調(diào)用 productA 的 operation1、operation2 方法 
  9.       productA.operation1(); 
  10.       productA.operation2(); 
  11.  
  12.       //獲取 productB 的對象 
  13.       Product productA = new ConcreateFactoryB().create(); 
  14.  
  15.       //調(diào)用 productB 的 operation1、operation2 方法 
  16.       productB.operation1(); 
  17.       productB.operation2(); 
  18.    } 
  • 執(zhí)行程序,輸出結(jié)果:
  1. 產(chǎn)品A,執(zhí)行任務(wù)1 
  2. 產(chǎn)品A,執(zhí)行任務(wù)2 
  3. 產(chǎn)品B,執(zhí)行任務(wù)1 
  4. 產(chǎn)品B,執(zhí)行任務(wù)2 

四、抽象工廠模式

抽象工廠模式主要是應(yīng)對產(chǎn)品族概念提出來的。提供一個創(chuàng)建一系列相關(guān)或相互依賴的對象。

  • 為形狀創(chuàng)建一個接口
  1. public interface Shape { 
  2.    void draw(); 
  • 創(chuàng)建實現(xiàn)接口的實體類
  1. public class Rectangle implements Shape { 
  2.   
  3.    @Override 
  4.    public void draw() { 
  5.       System.out.println("Inside Rectangle::draw() method."); 
  6.    } 
  1. public class Square implements Shape { 
  2.   
  3.    @Override 
  4.    public void draw() { 
  5.       System.out.println("Inside Square::draw() method."); 
  6.    } 
  1. public class Circle implements Shape { 
  2.   
  3.    @Override 
  4.    public void draw() { 
  5.       System.out.println("Inside Circle::draw() method."); 
  6.    } 
  • 為顏色創(chuàng)建一個接口
  1. public interface Color { 
  2.    void fill(); 
  • 創(chuàng)建實現(xiàn)接口的實體類
  1. public class Red implements Color { 
  2.   
  3.    @Override 
  4.    public void fill() { 
  5.       System.out.println("Inside Red::fill() method."); 
  6.    } 
  1. public class Green implements Color { 
  2.   
  3.    @Override 
  4.    public void fill() { 
  5.       System.out.println("Inside Green::fill() method."); 
  6.    } 
  1. public class Blue implements Color { 
  2.   
  3.    @Override 
  4.    public void fill() { 
  5.       System.out.println("Inside Blue::fill() method."); 
  6.    } 
  • 為 Color 和 Shape 對象創(chuàng)建抽象類來獲取工廠
  1. public abstract class AbstractFactory { 
  2.    public abstract Color getColor(String color); 
  3.    public abstract Shape getShape(String shape) ; 
  • 創(chuàng)建擴(kuò)展了 AbstractFactory 的工廠類,基于給定的信息生成實體類的對象
  1. public class ShapeFactory extends AbstractFactory { 
  2.      
  3.    @Override 
  4.    public Shape getShape(String shapeType){ 
  5.       if(shapeType == null){ 
  6.          return null
  7.       }         
  8.       if(shapeType.equalsIgnoreCase("CIRCLE")){ 
  9.          return new Circle(); 
  10.       } else if(shapeType.equalsIgnoreCase("RECTANGLE")){ 
  11.          return new Rectangle(); 
  12.       } else if(shapeType.equalsIgnoreCase("SQUARE")){ 
  13.          return new Square(); 
  14.       } 
  15.       return null
  16.    } 
  17.     
  18.    @Override 
  19.    public Color getColor(String color) { 
  20.       return null
  21.    } 
  1. public class ColorFactory extends AbstractFactory { 
  2.      
  3.    @Override 
  4.    public Shape getShape(String shapeType){ 
  5.       return null
  6.    } 
  7.     
  8.    @Override 
  9.    public Color getColor(String color) { 
  10.       if(color == null){ 
  11.          return null
  12.       }         
  13.       if(color.equalsIgnoreCase("RED")){ 
  14.          return new Red(); 
  15.       } else if(color.equalsIgnoreCase("GREEN")){ 
  16.          return new Green(); 
  17.       } else if(color.equalsIgnoreCase("BLUE")){ 
  18.          return new Blue(); 
  19.       } 
  20.       return null
  21.    } 
  • 創(chuàng)建一個工廠創(chuàng)造器/生成器類,通過傳遞形狀或顏色信息來獲取工廠
  1. public class FactoryProducer { 
  2.    public static AbstractFactory getFactory(String choice){ 
  3.       if(choice.equalsIgnoreCase("SHAPE")){ 
  4.          return new ShapeFactory(); 
  5.       } else if(choice.equalsIgnoreCase("COLOR")){ 
  6.          return new ColorFactory(); 
  7.       } 
  8.       return null
  9.    } 
  • 使用 FactoryProducer 來獲取 AbstractFactory,通過傳遞類型信息來獲取實體類的對象
  1. public class AbstractFactoryPatternDemo { 
  2.    public static void main(String[] args) { 
  3.   
  4.       //獲取形狀工廠 
  5.       AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE"); 
  6.   
  7.       //獲取形狀為 Circle 的對象 
  8.       Shape shape1 = shapeFactory.getShape("CIRCLE"); 
  9.   
  10.       //調(diào)用 Circle 的 draw 方法 
  11.       shape1.draw(); 
  12.   
  13.       //獲取形狀為 Rectangle 的對象 
  14.       Shape shape2 = shapeFactory.getShape("RECTANGLE"); 
  15.   
  16.       //調(diào)用 Rectangle 的 draw 方法 
  17.       shape2.draw(); 
  18.        
  19.       //獲取形狀為 Square 的對象 
  20.       Shape shape3 = shapeFactory.getShape("SQUARE"); 
  21.   
  22.       //調(diào)用 Square 的 draw 方法 
  23.       shape3.draw(); 
  24.   
  25.       //獲取顏色工廠 
  26.       AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR"); 
  27.   
  28.       //獲取顏色為 Red 的對象 
  29.       Color color1 = colorFactory.getColor("RED"); 
  30.   
  31.       //調(diào)用 Red 的 fill 方法 
  32.       color1.fill(); 
  33.   
  34.       //獲取顏色為 Green 的對象 
  35.       Color color2 = colorFactory.getColor("Green"); 
  36.   
  37.       //調(diào)用 Green 的 fill 方法 
  38.       color2.fill(); 
  39.   
  40.       //獲取顏色為 Blue 的對象 
  41.       Color color3 = colorFactory.getColor("BLUE"); 
  42.   
  43.       //調(diào)用 Blue 的 fill 方法 
  44.       color3.fill(); 
  45.    } 
  • 執(zhí)行程序,輸出結(jié)果:
  1. Inside Circle::draw() method. 
  2. Inside Rectangle::draw() method. 
  3. Inside Square::draw() method. 
  4. Inside Red::fill() method. 
  5. Inside Green::fill() method. 
  6. Inside Blue::fill() method. 

五、應(yīng)用

工廠模式在實際開發(fā)中使用非常頻繁,例如 JDK 中的日歷操作,在國際化的時候,獲取本地語言就用到簡單工廠模式。

寫一個獲取測試,如下:

  1. public static void main(String[] args) { 
  2.     //獲取日歷操作類 
  3.     Calendar calendar = Calendar.getInstance(); 
  4.  
  5.     int year = calendar.get(Calendar.YEAR); 
  6.     // 取月份要加1 
  7.     int month = calendar.get(Calendar.MONTH) + 1; 
  8.     int day = calendar.get(Calendar.DAY_OF_MONTH); 
  9.     int hour = calendar.get(Calendar.HOUR_OF_DAY); 
  10.     int minute = calendar.get(Calendar.MINUTE); 
  11.     int seconds = calendar.get(Calendar.SECOND); 
  12.     // 1-7分別代表 -- 星期日,星期一,星期二,星期三,星期四,星期五,星期六 
  13.     int week = calendar.get(calendar.DAY_OF_WEEK); 
  14.  
  15.     // 年-月-日 
  16.     System.out.println("year = " + year); 
  17.     System.out.println("month = " + month); 
  18.     System.out.println("day = " + day); 
  19.     //時-分-秒 
  20.     System.out.println("hour = " + hour); 
  21.     System.out.println("minute = " + minute); 
  22.     System.out.println("seconds = " + seconds); 
  23.  
  24.     // 星期 
  25.     System.out.println("week = " + week); 

進(jìn)入getInstance()方法,在獲取日歷類型的時候,內(nèi)容如下:

六、小結(jié)

工廠模式中,重要的是工廠類,而不是產(chǎn)品類。產(chǎn)品類可以是多種形式,多層繼承或者是單個類都是可以的。

但要明確的,工廠模式的接口只會返回一種類型的實例,這是在設(shè)計產(chǎn)品類的時候需要注意的,最好是有父類或者共同實現(xiàn)的接口。

上面介紹的三種工廠模式有各自的應(yīng)用場景,實際應(yīng)用時能解決問題滿足需求即可!

七、參考

1、菜鳥教程 - 工廠模式 

2、博客園 - alpha_panda - 設(shè)計模式之工廠模式

 

責(zé)任編輯:武曉燕 來源: Java極客技術(shù)
相關(guān)推薦

2014-12-19 10:09:47

2021-03-06 22:50:58

設(shè)計模式抽象

2011-11-17 16:03:05

Java工廠模式Clojure

2020-08-21 07:23:50

工廠模式設(shè)計

2022-01-12 13:33:25

工廠模式設(shè)計

2020-10-19 09:28:00

抽象工廠模式

2021-09-29 13:53:17

抽象工廠模式

2010-04-19 09:30:00

工廠模式PHP設(shè)計模式

2009-01-15 10:55:29

JavaScript設(shè)計模式抽象工廠

2024-07-31 08:12:33

2013-11-26 16:29:22

Android設(shè)計模式

2022-05-09 08:04:50

工廠模式設(shè)計模式

2010-10-09 09:25:35

Python工廠模式

2020-08-11 11:20:30

Typescript設(shè)計模式

2024-09-23 08:30:48

2019-08-16 10:46:46

JavaScript工廠模式抽象工廠模式

2011-07-28 09:50:58

設(shè)計模式

2015-11-03 09:43:43

avascript設(shè)計模式工廠模式

2024-09-14 08:24:44

設(shè)計模式抽象工廠模式JDK

2021-06-29 08:54:23

設(shè)計模式代理模式遠(yuǎn)程代理
點贊
收藏

51CTO技術(shù)棧公眾號