抽象工廠模式(Abstract Factory Pattern)

抽象工廠模式與工廠模式類似,也屬於創建型模式,提供了創建對象的最佳方式。

抽象工廠實際上是圍繞一個超級工廠創建其他工廠,而這個超級工廠本身又是其他工廠的工廠。抽象工廠模式中的接口負責創建一個相關對象的工廠,生成的每一個工廠都能按照工廠模式提供對象。

還是先簡單舉個例子理解一下抽象工廠模式。

抽象工廠設計模式我把它理解爲文件夾模式,在此我們只考慮3層文件夾。比如C盤下有一個文件夾叫做Abs,這個文件夾下又包含了Fac1和Fac2兩個文件夾,這兩個文件夾裏分別放了若干個同一類(在此體現爲同一後綴名)的子文件。那麼在此情境下,Abs文件夾就對應於抽象工廠模式中抽象工廠,它裏邊的兩個子文件夾就相當於繼承了Abs的兩個工廠類。而最底層的那些子文件就相當於一個個的實體類。這裏沒有指出工廠製造器的概念,但它不難理解。我們直接實現類圖就OK。


類圖如下所示:

第一步:創建形狀接口

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();  //創建方式和Shape相同
}

第四步:創建實現顏色接口的實體類

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.");
   }
}

第五步:爲Shape和Color創建抽象類(抽象工廠)獲取工廠

public abstract class AbstractFactory {
   public abstract Color getColor(String color);  // 抽象方法,返回值爲Color對象
   public abstract Shape getShape(String shape) ; // 抽象方法,返回值爲Shape對象
}

第六步:創建擴展了AbstractFactory的工廠類,基於給定信息生成實體類的對象

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) { //因爲這是形狀工廠類,所以getColor方法不予實現,但必須重寫
      return null;
   }
}
public class ColorFactory extends AbstractFactory {  // 此類與形狀工廠類類似,不再贅述
    
   @Override
   public Shape getShape(String shapeType){
      return null;
   }
   
   @Override
   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.

總結一下抽象工廠模式:

應用場景:系統的產品有多於一個的產品族,而系統只消費其中某一族的產品。

關鍵代碼:在一個工廠裏聚合多個同類產品。

優點:當一個產品族中的多個對象被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的對象。

缺點:產品族擴展非常困難,要增加一個系列的某一產品,既要在抽象的 Creator 里加代碼,又要在具體的裏面加代碼。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章