抽象工厂

抽象工廠模式（英語：Abstract factory pattern）是一種軟體開發設計模式。抽象工廠模式提供了一種方式，可以將一組具有同一主題的單獨的工廠封裝起來。在正常使用中，用戶端程式需要建立抽象工廠的具體實現，然後使用抽象工廠作為介面來建立這一主題的具體物件。用戶端程式不需要知道（或關心）它從這些內部的工廠方法中獲得物件的具體類型，因為用戶端程式僅使用這些物件的通用介面。抽象工廠模式將一組物件的實現細節與他們的一般使用分離開來。
舉個例子來說，比如一個抽象工廠類叫做DocumentCreator（文件建立器），此類提供建立若干種產品的介面，包括createLetter()（建立信件）和createResume()（建立簡歷）。其中，createLetter()返回一個Letter（信件），createResume()返回一個Resume（簡歷）。系統中還有一些DocumentCreator的具體實現類，包括FancyDocumentCreator和ModernDocumentCreator。這兩個類對DocumentCreator的兩個方法分別有不同的實現，用來建立不同的「信件」和「簡歷」（用FancyDocumentCreator的實體可以建立FancyLetter和FancyResume，用ModernDocumentCreator的實體可以建立ModernLetter和ModernResume）。這些具體的「信件」和「簡歷」類均繼承自抽象類，即Letter和Resume類。用戶端需要建立「信件」或「簡歷」時，先要得到一個合適的DocumentCreator實體，然後呼叫它的方法。一個工廠中建立的每個物件都是同一個主題的（「fancy」或者「modern」）。用戶端程式只需要知道得到的物件是「信件」或者「簡歷」，而不需要知道具體的主題，因此用戶端程式從抽象工廠DocumentCreator中得到了Letter或Resume類的參照，而不是具體類的物件參照。
「工廠」是建立產品（物件）的地方，其目的是將產品的建立與產品的使用分離。抽象工廠模式的目的，是將若干抽象產品的介面與不同主題產品的具體實現分離開。這樣就能在增加新的具體工廠的時候，不用修改參照抽象工廠的用戶端程式碼。
使用抽象工廠模式，能夠在具體工廠變化的時候，不用修改使用工廠的用戶端程式碼，甚至是在執行時。然而，使用這種模式或者相似的設計模式，可能給編寫程式碼帶來不必要的複雜性和額外的工作。正確使用設計模式能夠抵消這樣的「額外工作」。

定義

抽象工廠模式的實質是「提供介面，建立一系列相關或獨立的物件，而不指定這些物件的具體類。」

類圖

GuiFactory介面中的createButton方法返回Button類型的物件。返回Button的哪種實現依賴於使用GuiFactory的哪種實現。
需要注意的是，為了簡潔起見，以上類圖僅僅展示了建立一個類型物件的工廠。而在抽象工廠模式中，通常一個工廠能夠建立若干種不同類型的物件。

程式碼舉例

假設我們有兩種產品介面 Button 和 Border ，每一種產品都支援多種系列，比如 Mac 系列和 Windows 系列。這樣每個系列的產品分別是 MacButton, WinButton, MacBorder, WinBorder 。為了可以在執行時刻建立一個系列的產品族，我們可以為每個系列的產品族建立一個工廠 MacFactory 和 WinFactory 。每個工廠都有兩個方法 CreateButton 和 CreateBorder 並返回對應的產品，可以將這兩個方法抽象成一個介面 AbstractFactory 。這樣在執行時刻我們可以選擇建立需要的產品系列。

C++

我們的產品結構是這樣的
class Button; // Abstract Classclass MacButton: public Button {};class WinButton: public Button {};class Border; // Abstract Classclass MacBorder: public Border {};class WinBorder: public Border {};
對應的工廠是這樣的
class AbstractFactory {public:
    virtual Button* CreateButton() =0;
    virtual Border* CreateBorder() =0;};class MacFactory: public AbstractFactory {public:
    MacButton* CreateButton() { return new MacButton; }
    MacBorder* CreateBorder() { return new MacBorder; }};class WinFactory: public AbstractFactory {public:
    WinButton* CreateButton() { return new WinButton; }
    WinBorder* CreateBorder() { return new WinBorder; }};
那麼客戶可以根據需要選擇 Mac 風格或者 Win 風格來建立 Button 或 Border
AbstractFactory* fac;switch (style) {case MAC:
    fac = new MacFactory;
    break;case WIN:
    fac = new WinFactory;
    break;}Button* button = fac->CreateButton();Border* border = fac->CreateBorder();

PHP

<?php/*************************************************************************** *              AbstractFactory.php *              ------------------- *   Time  :    2006-11-11 *   Coder :    rollenc(http://www.rollenc.com) *              syre(http://syre.blogbus.com) ***************************************************************************/abstract class AbstractFactory {
abstract public function CreateButton();
abstract public function CreateBorder();}class MacFactory extends AbstractFactory{
public function CreateButton()
{
return new MacButton();
}
public function CreateBorder()
{
return new MacBorder();
}}class WinFactory extends AbstractFactory{
public function CreateButton()
{
return new WinButton();
}
public function CreateBorder()
{
return new WinBorder();
}}class Button{}class Border{}class MacButton extends Button{
function __construct()
{
echo 'MacButton is created' . "\n";
}}class MacBorder extends Border{
function __construct()
{
echo 'MacBorder is created' . "\n";
}}class WinButton extends Button{
function __construct()
{
echo 'WinButton is created' . "\n";
}}class WinBorder extends Border{
function __construct()
{
echo 'WinBorder is created' . "\n";
}}?>
那麼客戶可以根據需要選擇 Mac 風格或者 Win 風格的 Button 或 Border 來建立
<?$type = 'Mac'; //value by user.if(!in_array($type, array('Win','Mac')))
    die('Type Error');$factoryClass = $type.'Factory';$factory=new $factoryClass;$factory->CreateButton();$factory->CreateBorder();?>