---
# System prepended metadata

title: 抽象工廠模式
tags: [Design Pattern]

---

# 抽象工廠模式
###### tags: `Design Pattern`
> 可以創造一系列相關的對象 , 但不需要指定他的實體類別


## 概述
抽象工廠模式為各式產品都創造介面,然後確保所有的產品變體（相同的產品不同的風格）都繼承這些介面。
* 假如我們有 桌子 椅子 沙發 三種家具,同時他們又有各式各樣的風格(現代 \ 摩登 \ 維多利亞)
我們可以將所有風格的椅子都實做椅子這個介面 , 桌子沙發也都是相同的作法。
```cpp=
//椅子的介面
class Chair
{
    public:
    virtual void hasLegs() = 0;
    virtual void sitOn() = 0;
};

//所有的風格(變體)都去實做介面
class VictorianChair : public Chair
{
    public:
    void hasLegs() override{} ; 
    void sitOn() override{};
};
class ModernChair : public Chair
{
    public:
    void hasLegs() override{} ; 
    void sitOn() override{} ;
};
////其他的類別以此類推
```
接著 , 我們需要宣告一個"抽象工廠(Creator)"來負責創建所有產品的介面。
EX: createCharir , createSofa 之類的函數,同時這些函數必須要回傳"抽象的產品類型",也就是上放說的介面(Chair , Sofa , Coffee)。
```cpp=
//Creator的介面
class FurnitureFactory
{
    public:
    virtual Chair createChair() = 0;
    virtual CoffeeTable createCoffeeTable() = 0
    virtual Sofa createSofa() = 0;
};
//依照不同風格來創建他們的實做
class VictorianFurnitureFactory : public FurnitureFactory
{
    public:
    Chair createChair() override{}
    CoffeeTable createCoffeeTable() override{}
    Sofa createSofa() override{}
};

class ModernFurnitureFactory : public FurnitureFactory
{
    public:
    Chair createChair() override{}
    CoffeeTable createCoffeeTable() override{}
    Sofa createSofa() override{}
};
```
客戶端程式馬廄可以透過這個抽象工廠的方法,來獲得我們需要的產品。

## 範例
```cpp=
//產品A 介面
class ProdtctA
{
    public:
    virtual void dosome() = 0;
};
//實做產品A的風格1
class ProductA1 : public ProductA
{
    public:
    void dosome()
    {
        std::cout << "This is Product A1\n";
    }
};
//實做產品B的風格2
class ProductA2 : public ProductA
{
    public:
    void dosome()
    {
        std::cout << "This is Product A2\n";
    }
};

//產品b 介面
class ProdtctB
{
    public:
    virtual void dosome() = 0;
};
//實做產品A的風格1
class ProductB1 : public ProductB
{
    public:
    void dosome()
    {
        std::cout << "This is Product B1\n";
    }
};
//實做產品B的風格2
class ProductB2 : public ProductB
{
    public:
    void dosome()
    {
        std::cout << "This is Product B2\n";
    }
};
//抽象工廠 分別用來創建兩種產品
class AbstractFactory
{
    public:
    virtual std::shared_ptr<ProductA> createProductA() = 0;
    virtual std::shared_ptr<ProductB> createProductB() = 0;
};
//負責創建風格1的工廠 繼承抽象工廠
class ConcreteFactory1 : public AbstractFactory
{
    public:
    std::shared_ptr<ProductA> createProductA()
    {
        std::shared<ProductA> ptr = std::make_shared<ProductA1>();
        return ptr;
    }
    std::shared_ptr<ProductB> createProductB()
    {
        std::shared<ProductB> ptr = std::make_shared<ProductB1>();
        return ptr;
    }
};

//負責創建風格2的工廠 繼承抽象工廠
class ConcreteFactory2 : public AbstractFactory
{
    public:
    std::shared_ptr<ProductA> createProductA()
    {
        std::shared<ProductA> ptr = std::make_shared<ProductA2>();
        return ptr;
    }
    std::shared_ptr<ProductB> createProductB()
    {
        std::shared<ProductB> ptr = std::make_shared<ProductB2>();
        return ptr;
    }
};

class Clinet
{
    public:
    Clinet(std::shared_ptr<AbstractFactor> ptr)
    {
        abstract_ptr = ptr;
    }
    
    void someOperation()
    {
        abstract_ptr->dosome();
    }
    
    private:
    std::shared_ptr<AbstractFactor> abstract_ptr;
};
```