1. 程式人生 > >C++簡單實現幾種常用的設計模式

C++簡單實現幾種常用的設計模式

本文介紹幾種常用的設計模式並給出C++實現。

1.單例模式

作用:保證一個類只有一個例項,並提供一個訪問它的全域性訪問點,使得系統中只有唯一的一個物件例項

應用:常用於管理資源,如日誌、執行緒池

實現要點:

在類中,要構造一個例項,就必須呼叫類的建構函式,並且為了保證全域性只有一個例項,

防止在外部呼叫類的建構函式而構造例項,需要將建構函式的訪問許可權標記為private

同時阻止拷貝建立物件時賦值時拷貝物件,因此也將它們宣告並許可權標記為private;

另外,需要提供一個全域性訪問點,就需要在類中定義一個static函式,返回在類內部唯一構造的例項。

class Singleton{
public:
    static Singleton& getInstance(){
        static Singleton instance;
        return instance;
    }
    void printTest(){
        cout<<"do something"<<endl;
    }

private:
    Singleton(){}//防止外部呼叫構造建立物件
    Singleton(Singleton const &singleton);//阻止拷貝建立物件
    Singleton& operator=(Singleton const &singleton);//阻止賦值物件

};

int main()
{
    Singleton &a=Singleton::getInstance();
    a.printTest();
    return 0;
}

首先,建構函式宣告成private的目的是隻允許內部呼叫,getInstance()中的靜態區域性變數建立時呼叫,但不允許外部呼叫構造建立第二個例項;

然後,拷貝構造和拷貝賦值符是宣告成了private而不給出定義,其目的是阻止拷貝,如果企圖通過拷貝構造來建立第二個例項,編譯器會報錯。

阻止拷貝的另一種寫法是聲明後接一個"=delete",也能起到相同的作用(C++11)。

2.工廠模式

工廠模式包括三種:簡單工廠模式、工廠方法模式、抽象工廠模式。

工廠模式的主要作用是封裝物件的建立,分離物件的建立和操作過程,用於批量管理物件的建立過程,便於程式的維護和擴充套件。

(1)簡單工廠模式

簡單工廠是工廠模式最簡單的一種實現,對於不同產品的建立定義一個工廠類,將產品的型別作為引數傳入到工廠的建立函式,根據型別分支選擇不同的產品建構函式。

//簡單工廠模式
typedef enum ProductTypeTag
{
    TypeA,
    TypeB,
    TypeC
}PRODUCTTYPE;
class Product//產品抽象基類
{
public:
    virtual void Show() = 0;
};
class ProductA : public Product
{
public:
    void Show()
    {
        cout<<"I'm ProductA"<<endl;
    }
};
class ProductB : public Product
{
public:
    void Show()
    {
        cout<<"I'm ProductB"<<endl;
    }
};
class ProductC : public Product
{
public:
    void Show()
    {
        cout<<"I'm ProductC"<<endl;
    }
};
class Factory//工廠類
{
public:
    Product* CreateProduct(PRODUCTTYPE type)
    {
        switch (type)
        {
        case TypeA:
            return new ProductA();

        case TypeB:
            return new ProductB();

        case TypeC:
            return new ProductC();

        default:
            return NULL;
        }
    }
};

int main()
{
    Factory productCreator;
    Product *productA=productCreator.CreateProduct(TypeA);
    Product *productB=productCreator.CreateProduct(TypeB);
    Product *productC=productCreator.CreateProduct(TypeC);
    productA->Show();
    productB->Show();
    productC->Show();
    if(productA){
        delete productA;
        productA=NULL;
    }
    if(productB){
        delete productB;
        productB=NULL;
    }
    if(productC){
        delete productC;
        productC=NULL;
    }
    return 0;
}
(2)工廠方法模式

其實這才是正宗的工廠模式,簡單工廠模式只是一個簡單的對建立過程封裝。工廠方法模式在簡單工廠模式的基礎上增加對工廠的基類抽象,不同的產品建立採用不同的工廠建立(從工廠的抽象基類派生),這樣建立不同的產品過程就由不同的工廠分工解決:FactoryA專心負責生產ProductA,FactoryB專心負責生產ProductB,FactoryA和FactoryB之間沒有關係;如果到了後期,如果需要生產ProductC時,我們則可以建立一個FactoryC工廠類,該類專心負責生產ProductC類產品。

該模式相對於簡單工廠模式的優勢在於:便於後期產品種類的擴充套件。

//工廠方法模式
typedef enum ProductTypeTag
{
    TypeA,
    TypeB,
    TypeC
}PRODUCTTYPE;
class Product//產品抽象基類
{
public:
    virtual void Show() = 0;
};
class ProductA : public Product
{
public:
    void Show()
    {
        cout<<"I'm ProductA"<<endl;
    }
};
class ProductB : public Product
{
public:
    void Show()
    {
        cout<<"I'm ProductB"<<endl;
    }
};

class Factory//工廠類
{
public:
    virtual Product *createProduct()=0;
};
class FactoryA:public Factory{
public:
    Product *createProduct(){
        return new ProductA();
    }
};
class FactoryB:public Factory{
public:
    Product *createProduct(){
        return new ProductB();
    }
};
class FactoryC:public Factory{
public:
    Product *createProduct(){
        return new ProductC();
    }
};

int main()
{
        Factory *factoryA=new FactoryA();
        Product *productA = factoryA->createProduct();
        productA->Show();
        Factory *factoryB=new FactoryB();
        Product *productB = factoryB->createProduct();
        productB->Show();
        if (factoryA)
        {
            delete factoryA;
            factoryA = NULL;
        }
        if (factoryB)
        {
            delete factoryB;
            factoryB = NULL;
        }
        if (productA)
        {
            delete productA;
            productA = NULL;
        }
        if (productB)
        {
            delete productB;
            productB = NULL;
        }
        return 0;
}

(3)抽象工廠模式

抽象工廠模式對工廠方法模式進行了更加一般化的描述。工廠方法模式適用於產品種類結構單一的場合,為一類產品提供建立的介面;而抽象工廠方法適用於產品種類結構多的場合,就是當具有多個抽象產品型別時,抽象工廠便可以派上用場。

抽象工廠模式更適合實際情況,受生產線所限,讓低端工廠生產不同種類的低端產品,高階工廠生產不同種類的高階產品。

//抽象工廠模式
class ProductA
{
public:
    virtual void Show() = 0;
};
class ProductA1 : public ProductA//A類低端產品
{
public:
    void Show()
    {
        cout<<"I'm ProductA1"<<endl;
    }
};
class ProductA2 : public ProductA//A類高階產品
{
public:
    void Show()
    {
        cout<<"I'm ProductA2"<<endl;
    }
};
class ProductB
{
public:
    virtual void Show() = 0;
};
class ProductB1 : public ProductB//B類低端產品
{
public:
    void Show()
    {
        cout<<"I'm ProductB1"<<endl;
    }
};
class ProductB2 : public ProductB//B類高階產品
{
public:
    void Show()
    {
        cout<<"I'm ProductB2"<<endl;
    }
};

class Factory
{
public:
    virtual ProductA *CreateProductA() = 0;
    virtual ProductB *CreateProductB() = 0;
};

class Factory1 : public Factory//1號工廠用於生產低端產品
{
public:
    ProductA *CreateProductA()
    {
        return new ProductA1();
    }

    ProductB *CreateProductB()
    {
        return new ProductB1();
    }
};

class Factory2 : public Factory//2號工廠用於生產高階產品
{
    ProductA *CreateProductA()
    {
        return new ProductA2();
    }

    ProductB *CreateProductB()
    {
        return new ProductB2();
    }
};

int main()
{
    Factory *factory1 = new Factory1();
    ProductA *productA1 = factory1->CreateProductA();
    ProductB *productB1 = factory1->CreateProductB();
    productA1->Show();
    productB1->Show();

    Factory *factory2 = new Factory2();
    ProductA *productA2 = factory2->CreateProductA();
    ProductB *productB2 = factory2->CreateProductB();
    productA2->Show();
    productB2->Show();

    if (factory1)
    {
        delete factory1;
        factory1 = NULL;
    }
    if (productA1)
    {
        delete productA1;
        productA1= NULL;
    }
    if (productB1)
    {
        delete productB1;
        productB1 = NULL;
    }
    if (factory2)
    {
        delete factory2;
        factory2 = NULL;
    }
    if (productA2)
    {
        delete productA2;
        productA2 = NULL;
    }
    if (productB2)
    {
        delete productB2;
        productB2 = NULL;
    }
}