1. 程式人生 > >php 設計模式之抽象工廠模式

php 設計模式之抽象工廠模式

抽象工廠模式(Abstact Factory)是一種常見的軟體設計模式。該模式為一個產品族提供了統一的建立介面。當需要這個產品族的某一系列的時候,可以為此係列的產品族建立一個具體的工廠類。
一、意圖
抽象工廠模式提供一個建立一系統相關或相互依賴物件的介面,而無需指定它們具體的類【GOF95】
二、抽象工廠模式結構圖

 

三、抽象工廠模式中主要角色
抽象工廠(Abstract Factory)角色:它宣告一個建立抽象產品物件的介面。通常以介面或抽象類實現,所有的具體工廠類必須實現這個介面或繼承這個類。
具體工廠(Concrete Factory)角色:實現建立產品物件的操作。客戶端直接呼叫這個角色建立產品的例項。這個角色包含有選擇合適的產品物件的邏輯。通常使用具體類實現。
抽象產品(Abstract Product)角色:

宣告一類產品的介面。它是工廠方法模式所建立的物件的父類,或它們共同擁有的介面。
具體產品(Concrete Product)角色:實現抽象產品角色所定義的介面,定義一個將被相應的具體工廠建立的產品物件。其內部包含了應用程式的業務邏輯。
四、抽象工廠模式的優缺點
抽象工廠模式的優點:
1、分離了具體的類
2、使增加或替換產品族變得容易
3、有利於產品的一致性
抽象工廠模式的缺點: 難以支援新種類的產品。這是因為AbstractFactory介面確定了可以被建立的產品集合。支援新各類的產品就需要擴充套件訪工廠介面,從而導致AbstractFactory類及其所有子類的改變。
抽象工廠就是以一種傾斜的方式支援增加新的產品中,它為新產品族的增加提供了方便,而不能為新的產品等級結構的增加提供這樣的方便。
五、抽象工廠模式適用場景
以下情況應當使用抽象工廠模式:
1、一個系統不應當依賴於產品類例項如何被建立、組合和表達的細節,這對於所有形態的工廠模式都是重要的。
2、這個系統的產品有多於一個的產品族,而系統只消費其中某一族的產品。
3、 同屬於同一個產品族的產品是在一起使用的,這一約束必須在系統的設計中體現出來。
4、系統提供一個產品類的庫,所有的產品以同樣的接口出現,從而使用客戶端不依賴於實現
六、抽象工廠模式與其它模式
單例模式(singleton模式):具體工廠類可以設計成單例類,由於工廠通常有一個就可以,因此具體工廠子類一般都實現為一個Singleton。
工廠方法模式(factory method模式):抽象工廠建立產品的方法定義為工廠方法。
原型模式(prototype模式):如果有多個可能的產品系列,具體的工廠也可以使用原型模式,具體工廠使用產品系列中
每一個產品的原型進行例項化並且通過複製它的原型來建立新的產品。
七、抽象工廠模式PHP示例

<?php
/**
 * 抽象產品A
 */
interface AbstractProductA {

    /**
     * 取得產品名
     */
    public function getName();
}

/**
 * 抽象產品B
 */
interface AbstractProductB {

    /**
     * 取得產品名
     */
    public function getName();
}

/**
 * 具體產品A1
 */
class ProductA1 implements AbstractProductA {
    private $_name;

    public function __construct() {
        $this->_name = 'product A1';
    }

    public function getName() {
        return $this->_name;
    }
}


/**
 * 具體產品A2
 */
class ProductA2 implements AbstractProductA {
    private $_name;

    public function __construct() {
        $this->_name = 'product A2';
    }

    public function getName() {
        return $this->_name;
    }
}


/**
 * 具體產品B1
 */
class ProductB1 implements AbstractProductB {
    private $_name;

    public function __construct() {
        $this->_name = 'product B1';
    }

    public function getName() {
        return $this->_name;
    }
}

/**
 * 具體產品B2
 */
class ProductB2 implements AbstractProductB {
    private $_name;

    public function __construct() {
        $this->_name = 'product B2';
    }

    public function getName() {
        return $this->_name;
    }
}
/**
 * 抽象工廠
 */
interface AbstractFactory {
    /**
     * 建立等級結構為A的產品的工廠方法
     */
    public function createProductA();

    /**
     * 建立等級結構為B的產品的工廠方法
     */
    public function createProductB();

}

/**
 * 具體工廠1
 */
class ConcreteFactory1 implements AbstractFactory{

    public function createProductA() {
        return new ProductA1();
    }

    public function createProductB() {
        return new ProductB1();
    }
}


/**
 * 具體工廠2
 */
class ConcreteFactory2 implements AbstractFactory{

    public function createProductA() {
        return new ProductA2();
    }

    public function createProductB() {
        return new ProductB2();
    }
}




/**
 * 客戶端
 */
class Client {

    /**
     * Main program.
     */
    public static function main() {
        self::run(new ConcreteFactory1());
        self::run(new ConcreteFactory2());
    }

    /**
     * 呼叫工廠例項生成產品,輸出產品名
     * @param $factory AbstractFactory 工廠例項
     */
    public static function run(AbstractFactory $factory) {
        $productA = $factory->createProductA();
        $productB = $factory->createProductB();
        echo $productA->getName(), '<br />';
        echo $productB->getName(), '<br />';
    }

}

Client::main();
?>