設(shè)計(jì)模式[創(chuàng)建型]03--抽象工廠模式(Abstract Factory)

一、簡(jiǎn)介

抽象工廠模式(Abstract Factory Pattern):提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴(lài)對(duì)象的接口,而無(wú)須指定它們具體的類(lèi)。抽象工廠模式又稱(chēng)為Kit模式,屬于對(duì)象創(chuàng)建型模式。

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

二、類(lèi)結(jié)構(gòu)

抽象工廠模式結(jié)構(gòu)如下:

角色 類(lèi)別 簡(jiǎn)述
AbstractFactory 抽象工廠 一般是一個(gè)抽象類(lèi)或是接口
ConcreteFactory 具體工廠 用來(lái)創(chuàng)建一系列具體的產(chǎn)品
AbstractProduct 抽象產(chǎn)品 一個(gè)抽象類(lèi)或是接口
Product 具體產(chǎn)品 用來(lái)創(chuàng)建具體的產(chǎn)品

三、UML圖

比如,我們需要設(shè)計(jì)一個(gè)繪圖工具:

四、代碼分析

1、抽象產(chǎn)品

圖形類(lèi)接口:

interface Shape{
    public function draw();
}

顏色類(lèi)接口:

interface Color {
   public function fill();
}

2、具體產(chǎn)品

具體圖形類(lèi):

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

具體顏色類(lèi):

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

3、抽象工廠

為 Color 和 Shape 對(duì)象創(chuàng)建抽象類(lèi)來(lái)獲取工廠。

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

4、具體工廠

//形狀工廠類(lèi)
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;
    }
}

//顏色工廠類(lèi)
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、工廠創(chuàng)造器

創(chuàng)建一個(gè)工廠創(chuàng)造器/生成器類(lèi),通過(guò)傳遞形狀或顏色信息來(lái)獲取工廠。

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

6、使用實(shí)例

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

Demo::test();

測(cè)試結(jié)果:

插入一個(gè)圓形
插入一個(gè)矩形
填充紅色

五、特點(diǎn)

1、優(yōu)點(diǎn)

  • 抽象工廠模式隔離了具體類(lèi)的生成,使得客戶(hù)并不需要知道什么被創(chuàng)建。由于這種隔離,更換一個(gè)具體工廠就變得相對(duì)容易。所有的具體工廠都實(shí)現(xiàn)了抽象工廠中定義的那些公共接口,因此只需改變具體工廠的實(shí)例,就可以在某種程度上改變整個(gè)軟件系統(tǒng)的行為。另外,應(yīng)用抽象工廠模式可以實(shí)現(xiàn)高內(nèi)聚低耦合的設(shè)計(jì)目的,因此抽象工廠模式得到了廣泛的應(yīng)用。
  • 當(dāng)一個(gè)產(chǎn)品族中的多個(gè)對(duì)象被設(shè)計(jì)成一起工作時(shí),它能夠保證客戶(hù)端始終只使用同一個(gè)產(chǎn)品族中的對(duì)象。這對(duì)一些需要根據(jù)當(dāng)前環(huán)境來(lái)決定其行為的軟件系統(tǒng)來(lái)說(shuō),是一種非常實(shí)用的設(shè)計(jì)模式。
  • 增加新的具體工廠和產(chǎn)品族很方便,無(wú)須修改已有系統(tǒng),符合“開(kāi)閉原則”。

2、缺點(diǎn)

  • 在添加新的產(chǎn)品對(duì)象時(shí),難以擴(kuò)展抽象工廠來(lái)生產(chǎn)新種類(lèi)的產(chǎn)品,這是因?yàn)樵诔橄蠊S角色中規(guī)定了所有可能被創(chuàng)建的產(chǎn)品集合,要支持新種類(lèi)的產(chǎn)品就意味著要對(duì)該接口進(jìn)行擴(kuò)展,而這將涉及到對(duì)抽象工廠角色及其所有子類(lèi)的修改,顯然會(huì)帶來(lái)較大的不便。
  • 開(kāi)閉原則的傾斜性(增加新的工廠和產(chǎn)品族容易,增加新的產(chǎn)品等級(jí)結(jié)構(gòu)麻煩)。。

3、適用場(chǎng)景

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

  • 一個(gè)系統(tǒng)不應(yīng)當(dāng)依賴(lài)于產(chǎn)品類(lèi)實(shí)例如何被創(chuàng)建、組合和表達(dá)的細(xì)節(jié),這對(duì)于所有類(lèi)型的工廠模式都是重要的。
  • 系統(tǒng)中有多于一個(gè)的產(chǎn)品族,而每次只使用其中某一產(chǎn)品族。
  • 屬于同一個(gè)產(chǎn)品族的產(chǎn)品將在一起使用,這一約束必須在系統(tǒng)的設(shè)計(jì)中體現(xiàn)出來(lái)。
  • 系統(tǒng)提供一個(gè)產(chǎn)品類(lèi)的庫(kù),所有的產(chǎn)品以同樣的接口出現(xiàn),從而使客戶(hù)端不依賴(lài)于具體實(shí)現(xiàn)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容