設計模式03--抽象工廠模式(Abstract Factory)

一、簡介

抽象工廠模式(Abstract Factory Pattern):提供一個創建一系列相關或相互依賴對象的接口,而無須指定它們具體的類。抽象工廠模式又稱爲Kit模式,屬於對象創建型模式。

注意:這裏和工廠方法的區別是:一系列(多個),而工廠方法只有一個。

二、類結構

抽象工廠模式結構如下:

角色 類別 簡述
AbstractFactory 抽象工廠 一般是一個抽象類或是接口
ConcreteFactory 具體工廠 用來創建一系列具體的產品
AbstractProduct 抽象產品 一個抽象類或是接口
Product 具體產品 用來創建具體的產品

三、UML圖

比如,我們需要設計一個繪圖工具:

四、類實現

1、抽象產品

圖形類接口:

interface Shape{
    public function draw();
}

顏色類接口:

interface Color {
   public function fill();
}

2、具體產品

具體圖形類:

//矩形類
class Rectangle implements Shape {
    public function draw() {
        echo '插入一個矩形 \n\r';
    }
}
//正方形類
class Square implements Shape {
    public function draw() {
        echo '插入一個正方形 \n\r';
    }
}
//圓形類
class Circle implements Shape {
    public function draw() {
        echo '插入一個圓形 \n\r';
    }
}

具體顏色類:

//紅色類
class Red implements Color {
    public function fill() {
        echo '填充紅色 \n\r';
    }
}
//綠色類
class Green implements Color {
    public function fill() {
        echo '填充綠色 \n\r';
    }
}
//藍色類
class Blue implements Color {
    public function fill() {
        echo '填充藍色 \n\r';
    }
}

3、抽象工廠

爲 Color 和 Shape 對象創建抽象類來獲取工廠。

class interface AbstractFactory {
   public function getColor($color);
   public function getShape($shape) ;
}

4、具體工廠

//形狀工廠類
class ShapeFactory extends AbstractFactory {

    public function getShape($shapeType){
        if($shapeType == false){
            return false;
        }        
        if($shapeType=="circle"){
            return new Circle();
        } else if($shapeType=="rectangle"){
            return new Rectangle();
        } else if($shapeType=="square"){
            return new Square();
        }
        return false;
    }
    
    public function getColor($color) {
        return false;
    }
}

//顏色工廠類
class ColorFactory extends AbstractFactory {

    public function getShape($shapeType){
        return false;
    }
   
    public function getColor($color) {
        if($color == false){
            return false;
        }
        if($color=="red"){
            return new Red();
        } else if($color=="green"){
            return new Green();
        } else if($color=="blue"){
            return new Blue();
        }
        return false;
    }
}

5、工廠創造器

創建一個工廠創造器/生成器類,通過傳遞形狀或顏色信息來獲取工廠。

class FactoryProducer {
    public static function getFactory($choice){
        if($choice=="shape")){
            return new ShapeFactory();
        } else if($choice=="color"){
            return new ColorFactory();
        }
        return null;
    }
}

6、使用實例

public class Demo {
   public static function test() {
 
      //獲取形狀工廠
      $shapeFactory = FactoryProducer::getFactory("SHAPE");
      
      //爲形狀插入Circle對象
      $shape1 = $shapeFactory->getShape("circle");
      //調用 Circle 的 draw 方法
      $shape1->draw();
 
      //爲形狀插入Rectangle對象
      $shape2 = $shapeFactory->getShape("rectangle");
      //調用 Rectangle 的 draw 方法
      $shape2->draw();
      
      //獲取顏色工廠
      $colorFactory = FactoryProducer::getFactory("color");
 
      //獲取顏色爲 Red 的對象
      $color1 = $colorFactory->getColor("red");
      //調用 Red 的 fill 方法
      $color1->fill();
   }
}

Demo::test();

測試結果:

插入一個圓形
插入一個矩形
填充紅色

五、特點

1、優點

  • 抽象工廠模式隔離了具體類的生成,使得客戶並不需要知道什麼被創建。由於這種隔離,更換一個具體工廠就變得相對容易。所有的具體工廠都實現了抽象工廠中定義的那些公共接口,因此只需改變具體工廠的實例,就可以在某種程度上改變整個軟件系統的行爲。另外,應用抽象工廠模式可以實現高內聚低耦合的設計目的,因此抽象工廠模式得到了廣泛的應用。
  • 當一個產品族中的多個對象被設計成一起工作時,它能夠保證客戶端始終只使用同一個產品族中的對象。這對一些需要根據當前環境來決定其行爲的軟件系統來說,是一種非常實用的設計模式。
  • 增加新的具體工廠和產品族很方便,無須修改已有系統,符合“開閉原則”。

2、缺點

  • 在添加新的產品對象時,難以擴展抽象工廠來生產新種類的產品,這是因爲在抽象工廠角色中規定了所有可能被創建的產品集合,要支持新種類的產品就意味着要對該接口進行擴展,而這將涉及到對抽象工廠角色及其所有子類的修改,顯然會帶來較大的不便。
  • 開閉原則的傾斜性(增加新的工廠和產品族容易,增加新的產品等級結構麻煩)。。

3、適用場景

在以下情況下可以考慮使用抽象工廠模式:

  • 一個系統不應當依賴於產品類實例如何被創建、組合和表達的細節,這對於所有類型的工廠模式都是重要的。
  • 系統中有多於一個的產品族,而每次只使用其中某一產品族。
  • 屬於同一個產品族的產品將在一起使用,這一約束必須在系統的設計中體現出來。
  • 系統提供一個產品類的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴於具體實現。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章