工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一,今天我們一起來徹底解析一下她。
一、介紹
從名稱上,顧名思義就是創建產品,按類別分為簡單工廠模式、工廠方法模式、抽象工廠模式,主要功能都是幫助我們把對象的實例化操作單獨抽取出來,優化系統架構,增強系統的擴展性。
下面,我們一起來看看各個模式的使用方式。
二、簡單工廠模式
簡單工廠模式,對象創建管理方式最為簡單,因為其僅僅簡單的對不同類對象的創建進行了一層薄薄的封裝。該模式通過向工廠傳遞類型來指定要創建的對象。
public interface Product { void operation1(); void operation2();}
public class ConcreateProductA implements Product{ @Override public void operation1() { System.out.println("產品A,執行任務1"); } @Override public void operation2() { System.out.println("產品A,執行任務2"); }}
public class ConcreateProductB implements Product{ @Override public void operation1() { System.out.println("產品B,執行任務1"); } @Override public void operation2() { System.out.println("產品B,執行任務2"); }}
public class SimpleFactory { //使用 create 方法獲取形狀類型的對象 public Product create(String productType){ if(productType == null){ return null; } if(productType.equalsIgnoreCase("productA")){ return new ConcreateProductA(); } if(productType.equalsIgnoreCase("productB")){ return new ConcreateProductB(); } return null; }}
public class FactoryPatternDemo { public static void main(String[] args) { SimpleFactory simpleFactory = new SimpleFactory(); //獲取 productA 的對象 Product productA = simpleFactory.create("productA"); //調用 productA 的 operation1、operation2 方法 productA.operation1(); productA.operation2(); //獲取 productB 的對象 Product productB = simpleFactory.create("productB"); //調用 productB 的 operation1、operation2 方法 productB.operation1(); productB.operation2(); }}
產品A,執行任務1產品A,執行任務2產品B,執行任務1產品B,執行任務2
當然,還可以將創建對象方式進行改進,將SimpleFactory類創建對象的方式改成如下方式:
public class SimpleFactory { //反射機制獲取實體類 public <T> T createByClazzName(Class<? extends T> clazz){ T obj = null; try { obj = (T) Class.forName(clazz.getName()).newInstance(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return obj; }}
這樣做的好處是,當有新的產品加入時,不用修改工廠類,在調用的時候,采用如下方式即可獲取對象!
Product product = new SimpleFactory().create("類名.class");
三、工廠方法模式
和簡單工廠模式中工廠負責生產所有產品相比,工廠方法模式將生成具體產品的任務分發給具體的產品工廠。
public interface FactoryProduct { Product create();}
public class ConcreateFactoryA implements FactoryProduct{ @Override public Product create() { return new ConcreateProductA(); }}
public class ConcreateFactoryB implements FactoryProduct{ @Override public Product create() { return new ConcreateProductB(); }}
public class FactoryPatternDemo { public static void main(String[] args) { //獲取 productA 的對象 Product productA = new ConcreateFactoryA().create(); //調用 productA 的 operation1、operation2 方法 productA.operation1(); productA.operation2(); //獲取 productB 的對象 Product productA = new ConcreateFactoryB().create(); //調用 productB 的 operation1、operation2 方法 productB.operation1(); productB.operation2(); }}
產品A,執行任務1產品A,執行任務2產品B,執行任務1產品B,執行任務2
四、抽象工廠模式
抽象工廠模式主要是應對產品族概念提出來的。提供一個創建一系列相關或相互依賴的對象。
public interface Shape { void draw();}
public class Rectangle implements Shape { @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); }}
public class Square implements Shape { @Override public void draw() { System.out.println("Inside Square::draw() method."); }}
public class Circle implements Shape { @Override public void draw() { System.out.println("Inside Circle::draw() method."); }}
public interface Color { void fill();}
public class Red implements Color { @Override public void fill() { System.out.println("Inside Red::fill() method."); }}
public class Green implements Color { @Override public void fill() { System.out.println("Inside Green::fill() method."); }}
public class Blue implements Color { @Override public void fill() { System.out.println("Inside Blue::fill() method."); }}
public abstract class AbstractFactory { public abstract Color getColor(String color); public abstract Shape getShape(String shape) ;}
public class ShapeFactory extends AbstractFactory { @Override public Shape getShape(String shapeType){ if(shapeType == null){ return null; } if(shapeType.equalsIgnoreCase("CIRCLE")){ return new Circle(); } else if(shapeType.equalsIgnoreCase("RECTANGLE")){ return new Rectangle(); } else if(shapeType.equalsIgnoreCase("SQUARE")){ return new Square(); } return null; } @Override public Color getColor(String color) { return null; }}
public class ColorFactory extends AbstractFactory { @Override public Shape getShape(String shapeType){ return null; } @Override public Color getColor(String color) { if(color == null){ return null; } if(color.equalsIgnoreCase("RED")){ return new Red(); } else if(color.equalsIgnoreCase("GREEN")){ return new Green(); } else if(color.equalsIgnoreCase("BLUE")){ return new Blue(); } return null; }}
public class FactoryProducer { public static AbstractFactory getFactory(String choice){ if(choice.equalsIgnoreCase("SHAPE")){ return new ShapeFactory(); } else if(choice.equalsIgnoreCase("COLOR")){ return new ColorFactory(); } return null; }}
public class AbstractFactoryPatternDemo { public static void main(String[] args) { //獲取形狀工廠 AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE"); //獲取形狀為 Circle 的對象 Shape shape1 = shapeFactory.getShape("CIRCLE"); //調用 Circle 的 draw 方法 shape1.draw(); //獲取形狀為 Rectangle 的對象 Shape shape2 = shapeFactory.getShape("RECTANGLE"); //調用 Rectangle 的 draw 方法 shape2.draw(); //獲取形狀為 Square 的對象 Shape shape3 = shapeFactory.getShape("SQUARE"); //調用 Square 的 draw 方法 shape3.draw(); //獲取顏色工廠 AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR"); //獲取顏色為 Red 的對象 Color color1 = colorFactory.getColor("RED"); //調用 Red 的 fill 方法 color1.fill(); //獲取顏色為 Green 的對象 Color color2 = colorFactory.getColor("Green"); //調用 Green 的 fill 方法 color2.fill(); //獲取顏色為 Blue 的對象 Color color3 = colorFactory.getColor("BLUE"); //調用 Blue 的 fill 方法 color3.fill(); }}
Inside Circle::draw() method.Inside Rectangle::draw() method.Inside Square::draw() method.Inside Red::fill() method.Inside Green::fill() method.Inside Blue::fill() method.
五、應用
工廠模式在實際開發中使用非常頻繁,例如 JDK 中的日歷操作,在國際化的時候,獲取本地語言就用到簡單工廠模式。
寫一個獲取測試,如下:
public static void main(String[] args) { //獲取日歷操作類 Calendar calendar = Calendar.getInstance(); int year = calendar.get(Calendar.YEAR); // 取月份要加1 int month = calendar.get(Calendar.MONTH) + 1; int day = calendar.get(Calendar.DAY_OF_MONTH); int hour = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE); int seconds = calendar.get(Calendar.SECOND); // 1-7分別代表 -- 星期日,星期一,星期二,星期三,星期四,星期五,星期六 int week = calendar.get(calendar.DAY_OF_WEEK); // 年-月-日 System.out.println("year = " + year); System.out.println("month = " + month); System.out.println("day = " + day); //時-分-秒 System.out.println("hour = " + hour); System.out.println("minute = " + minute); System.out.println("seconds = " + seconds); // 星期 System.out.println("week = " + week);}
進入getInstance()方法,在獲取日歷類型的時候,內容如下:
六、小結
工廠模式中,重要的是工廠類,而不是產品類。產品類可以是多種形式,多層繼承或者是單個類都是可以的。
但要明確的,工廠模式的接口只會返回一種類型的實例,這是在設計產品類的時候需要注意的,最好是有父類或者共同實現的接口。
上面介紹的三種工廠模式有各自的應用場景,實際應用時能解決問題滿足需求即可!
原文鏈接:https://mp.weixin.qq.com/s/uPl3MpA38ZwOwk6VWtdipA