1. 程式人生 > 其它 >C++設計模式——工廠模式

C++設計模式——工廠模式

轉載來自:https://www.cnblogs.com/xiaolincoding/p/11524376.html

什麼是工廠模式?

這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。
在工廠模式中,我們在建立物件時不會對客戶端暴露建立邏輯,並且是通過使用一個共同的介面來指向新建立的物件。

簡單來說,使用了C++多型的特性將存在繼承關係的類通過一個工廠類建立對應的子類(派生類)物件。在專案複雜的情況下,可以便於子類物件的建立。

工廠模式的實現方式可分別簡單工廠模式工廠方法模式抽象工廠模式,每個實現方式都存在優和劣。

最近炒鞋炒的非常的火,那麼以鞋廠的形式,一一分析針對每個實現方式進行分析。


簡單工廠模式

具體的情形:
  • 鞋廠可以指定生產耐克、阿迪達斯和李寧牌子的鞋子。哪個鞋炒的火爆,老闆就生產哪個,看形勢生產。
UML圖:
簡單工廠模式的結構組成
  1. 工廠類(ShoesFactory):工廠模式的核心類,會定義一個用於建立指定的具體例項物件的介面。
  2. 抽象產品類(Shoes):是具體產品類的繼承的父類或實現的介面
  3. 具體產品類(NiKeShoes\AdidasShoes\LiNingShoes):工廠類所建立的物件就是此具體產品例項。
簡單工廠模式的特點
  • 工廠類封裝了建立具體產品物件的函數。
簡單工廠模式的缺陷
  • 擴充套件性非常差,新增產品的時候,需要去修改工廠類
簡單工廠模式的程式碼
  • Shoes為鞋子的抽象類(基類),介面函式為Show(),用於顯示鞋子廣告。
  • NiKeShoesAdidasShoesLiNingShoes為具體鞋子的類,分別是耐克、阿迪達斯和李寧鞋牌的鞋,它們都繼承於Shoes抽象類。#include <iostream>
#include <iostream>
#include <algorithm>
#include <cstdio>
// 鞋子抽象類
class Shoes
{
public:
    virtual ~Shoes() {}
    virtual void
Show() = 0; }; // 耐克鞋子 class NiKeShoes : public Shoes { public: void Show() { std::cout << "我是耐克球鞋,我的廣告語:Just do it" << std::endl; } }; // 阿迪達斯鞋子 class AdidasShoes : public Shoes { public: void Show() { std::cout << "我是阿迪達斯球鞋,我的廣告語:Impossible is nothing" << std::endl; } }; // 李寧鞋子 class LiNingShoes : public Shoes { public: void Show() { std::cout << "我是李寧球鞋,我的廣告語:Everything is possible" << std::endl; } }; enum SHOES_TYPE { NIKE, LINING, ADIDAS }; // 總鞋廠 class ShoesFactory { public: // 根據鞋子型別建立對應的鞋子物件 Shoes* CreateShoes(SHOES_TYPE type) { switch (type) { case NIKE: return new NiKeShoes(); break; case LINING: return new LiNingShoes(); break; case ADIDAS: return new AdidasShoes(); break; default: return NULL; break; } } }; int main() { // 構造工廠物件 ShoesFactory shoesFactory; // 從鞋工廠物件建立阿迪達斯鞋物件 Shoes* pNikeShoes = shoesFactory.CreateShoes(NIKE); if (pNikeShoes != nullptr) { // 耐克球鞋廣告喊起 pNikeShoes->Show(); // 釋放資源 delete pNikeShoes; pNikeShoes = nullptr; } // 從鞋工廠物件建立阿迪達斯鞋物件 Shoes* pLiNingShoes = shoesFactory.CreateShoes(LINING); if (pLiNingShoes != nullptr) { // 李寧球鞋廣告喊起 pLiNingShoes->Show(); // 釋放資源 delete pLiNingShoes; pLiNingShoes = nullptr; } // 從鞋工廠物件建立阿迪達斯鞋物件 Shoes* pAdidasShoes = shoesFactory.CreateShoes(ADIDAS); if (pAdidasShoes != nullptr) { // 阿迪達斯球鞋廣告喊起 pAdidasShoes->Show(); // 釋放資源 delete pAdidasShoes; pAdidasShoes = nullptr; } return 0; }
  • main函式,先是構造了工廠物件,後建立指定型別的具體鞋子產品物件,建立了具體鞋子產品的物件便可直接列印廣告。因為採用的是new的方式建立了物件,用完了要通過delete釋放資源資源哦!

工廠方法模式

具體情形:
  • 現各類鞋子炒的非常火熱,於是為了大量生產每種型別的鞋子,則要針對不同品牌的鞋子開設獨立的生產線,那麼每個生產線就只能生產同類型品牌的鞋。
UML圖:
工廠方法模式的結構組成
  1. 抽象工廠類廠(ShoesFactory):工廠方法模式的核心類,提供建立具體產品的介面,由具體工廠類實現。
  2. 具體工廠類NiKeProducer\AdidasProducer\LiNingProducer):繼承於抽象工廠,實現建立對應具體產品物件的方式。
  3. 抽象產品類Shoes):它是具體產品繼承的父類(基類)。
  4. 具體產品類NiKeShoes\AdidasShoes\LiNingShoes):具體工廠所建立的物件,就是此類。
工廠方法模式的特點
  • 工廠方法模式抽象出了工廠類,提供建立具體產品的介面,交由子類去實現。
  • 工廠方法模式的應用並不只是為了封裝具體產品物件的建立,而是要把具體產品物件的建立放到具體工廠類實現。
工廠方法模式的缺陷
  • 每新增一個產品,就需要增加一個對應的產品的具體工廠類。相比簡單工廠模式而言,工廠方法模式需要更多的類定義。
  • 一條生產線只能一個產品。
工廠方法模式的程式碼:
  • ShoesFactory抽象工廠類,提供了建立具體鞋子產品的純虛擬函式。
  • NiKeProducerAdidasProducerLiNingProducer具體工廠類,繼承持續工廠類,實現對應具體鞋子產品物件的建立。
#include <iostream>
#include <algorithm>
#include <cstdio>
enum SHOES_TYPE
{
    NIKE,
    LINING,
    ADIDAS
};
// 鞋子抽象類
class Shoes
{
public:
    virtual ~Shoes() {}
    virtual void Show() = 0;
};

// 耐克鞋子
class NiKeShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是耐克球鞋,我的廣告語:Just do it" << std::endl;
    }
};

// 阿迪達斯鞋子
class AdidasShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是阿迪達斯球鞋,我的廣告語:Impossible is nothing" << std::endl;
    }
};

// 李寧鞋子
class LiNingShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是李寧球鞋,我的廣告語:Everything is possible" << std::endl;
    }
};


// 總鞋廠
class ShoesFactory
{
public:
    virtual Shoes* CreateShoes() = 0;
    virtual ~ShoesFactory() {}
};


// 耐克生產者/生產鏈
class NiKeProducer : public ShoesFactory
{
public:
    Shoes* CreateShoes()
    {
        return new NiKeShoes();
    }
};

// 阿迪達斯生產者/生產鏈
class AdidasProducer : public ShoesFactory
{
public:
    Shoes* CreateShoes()
    {
        return new AdidasShoes();
    }
};

// 李寧生產者/生產鏈
class LiNingProducer : public ShoesFactory
{
public:
    Shoes* CreateShoes()
    {
        return new LiNingShoes();
    }
};

int main()
{
    // ================ 生產耐克流程 ==================== //
    // 鞋廠開設耐克生產線
    ShoesFactory* niKeProducer = new NiKeProducer();
    // 耐克生產線產出球鞋
    Shoes* nikeShoes = niKeProducer->CreateShoes();
    // 耐克球鞋廣告喊起
    nikeShoes->Show();
    // 釋放資源
    delete nikeShoes;
    delete niKeProducer;

    // ================ 生產阿迪達斯流程 ==================== //
    // 鞋廠開設阿迪達斯生產者
    ShoesFactory* adidasProducer = new AdidasProducer();
    // 阿迪達斯生產線產出球鞋
    Shoes* adidasShoes = adidasProducer->CreateShoes();
    // 阿迪達斯球鞋廣喊起
    adidasShoes->Show();
    // 釋放資源
    delete adidasShoes;
    delete adidasProducer;

    return 0;
}

結果:


抽象工廠模式

具體情形:
  • 鞋廠為了擴大了業務,不僅只生產鞋子,把運動品牌的衣服也一起生產了。
UML圖:
抽象工廠模式的結構組成(和工廠方法模式一樣):
  1. 抽象工廠類廠(ShoesFactory):工廠方法模式的核心類,提供建立具體產品的介面,由具體工廠類實現。
  2. 具體工廠類NiKeProducer):繼承於抽象工廠,實現建立對應具體產品物件的方式。
  3. 抽象產品類Shoes\Clothe):它是具體產品繼承的父類(基類)。
  4. 具體產品類NiKeShoes\NiKeClothe):具體工廠所建立的物件,就是此類。
抽象工廠模式的特點:
  • 提供一個介面,可以建立多個產品族中的產品物件。如建立耐克工廠,則可以建立耐克鞋子產品、衣服產品、褲子產品等。
抽象工廠模式的缺陷:
  • 同工廠方法模式一樣,新增產品時,都需要增加一個對應的產品的具體工廠類。
抽象工廠摸是的程式碼:
  • ClotheShoes,分別為衣服和鞋子的抽象產品類。
  • NiKeClotheNiKeShoes,分別是耐克衣服和耐克衣服的具體產品類。
#include <iostream>
#include <algorithm>
#include <cstdio>
enum SHOES_TYPE
{
    NIKE,
    LINING,
    ADIDAS
};
// 鞋子抽象類
class Shoes
{
public:
    virtual ~Shoes() {}
    virtual void Show() = 0;
};

// 耐克鞋子
class NiKeShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是耐克球鞋,我的廣告語:Just do it" << std::endl;
    }
};

// 阿迪達斯鞋子
class AdidasShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是阿迪達斯球鞋,我的廣告語:Impossible is nothing" << std::endl;
    }
};

// 李寧鞋子
class LiNingShoes : public Shoes
{
public:
    void Show()
    {
        std::cout << "我是李寧球鞋,我的廣告語:Everything is possible" << std::endl;
    }
};


// 基類 衣服
class Clothe
{
public:
    virtual void Show() = 0;
    virtual ~Clothe() {}
};

// 耐克衣服
class NiKeClothe : public Clothe
{
public:
    void Show()
    {
        std::cout << "我是耐克衣服,時尚我最在行!" << std::endl;
    }
};


// 總廠
class Factory
{
public:
    virtual Shoes* CreateShoes() = 0;
    virtual Clothe* CreateClothe() = 0;
    virtual ~Factory() {}
};


// 耐克生產者/生產鏈
class NiKeProducer : public Factory
{
public:
    Shoes* CreateShoes()
    {
        return new NiKeShoes();
    }
    Clothe* CreateClothe()
    {
        return new NiKeClothe();
    }
};

// 阿迪達斯生產者/生產鏈
class AdidasProducer : public Factory
{
public:
    Shoes* CreateShoes()
    {
        return new AdidasShoes();
    }
};

// 李寧生產者/生產鏈
class LiNingProducer : public Factory
{
public:
    Shoes* CreateShoes()
    {
        return new LiNingShoes();
    }
};

int main()
{
    // ================ 生產耐克流程 ==================== //
    // 鞋廠開設耐克生產線
    Factory* niKeProducer = new NiKeProducer();

    // 耐克生產線產出球鞋
    Shoes* nikeShoes = niKeProducer->CreateShoes();
    // 耐克生產線產出衣服
    Clothe* nikeClothe = niKeProducer->CreateClothe();

    // 耐克球鞋廣告喊起
    nikeShoes->Show();
    // 耐克衣服廣告喊起
    nikeClothe->Show();

    // 釋放資源
    delete nikeShoes;
    delete nikeClothe;
    delete niKeProducer;
    return 0;
}