C++常見三種工廠設計模式

設計模式

簡單工廠模式

  • 簡單工廠模式:主要特點是需要在工廠類中做判斷,從而創造相應的產品,當增加新產品時,需要修改工廠類。

  • 使用場景

    工廠類負責創建的對象比較少;

    客戶只知道傳入工廠類的參數,對於如何創建對象(邏輯)不關心;

    由於簡單工廠很容易違反高內聚責任分配原則,因此一般只在很簡單的情況下應用。

  • 代碼

    //算法的父類,抽象出返回結果的接口
    class Operation
    {
    public:
        virtual int GetResult() =0;
    public:
        double m_Num1;
        double m_Num2;
    };
    //工廠類,用於生產相應的算法子類
    class OperationFactry
    {
    public:
        OperationFactry(void);
        ~OperationFactry(void);
    public:
        static Operation* CreateOperate(int n )
        {
            switch(n)
            {
            case 1:
                return new OperationAdd;
                break;
            }
        }
    };
    //算法子類,由工廠類創建,重寫父類中的虛函數
    class OperationAdd:Public Operation
    {
    public:
        int GetResult();
    };
    

工廠方法模式

  • 工廠方法模式

    • 是一種常用的類創建型設計模式,此模式的核心精神是封裝類中變化的部分,提取其中個性化善變的部分爲獨立類,通過依賴注入以達到解耦、複用和方便後期維護拓展的目的。它的核心結構有四個角色,分別是抽象工廠;具體工廠;抽象產品;具體產品。

    • 工廠方法模式對簡單工廠模式進行了抽象。有一個抽象的Factory類(可以是抽象類和接口),這個類將不再負責具體的產品生產,而是隻制定一些規範,具體的生產工作由其子類去完成。在這個模式中,工廠類和產品類往往可以依次對應。即一個抽象工廠對應一個抽象產品,一個具體工廠對應一個具體產品,這個具體的工廠就負責生產對應的產品。

  • 角色結構

    • 抽象工廠(Creator)角色:是工廠方法模式的核心,與應用程序無關。任何在模式中創建的對象的工廠類必須實現這個接口。

    • 具體工廠(Concrete Creator)角色:這是實現抽象工廠接口的具體工廠類,包含與應用程序密切相關的邏輯,並且受到應用程序調用以創建產品對象。在上圖中有兩個這樣的角色:BulbCreator與TubeCreator。

    • 抽象產品(Product)角色:工廠方法模式所創建的對象的超類型,也就是產品對象的共同父類或共同擁有的接口。在上圖中,這個角色是Light。

    • 具體產品(Concrete Product)角色:這個角色實現了抽象產品角色所定義的接口。某具體產品有專門的具體工廠創建,它們之間往往一一對應。

  • 代碼

    //抽象產品角色
    class Tank
    {
    public:
        virtual void message() = 0;
    };
    
    //具體的產品類
    class Tank80:public Tank
    {
    public:
        void message()
        {
            cout << "Tank80" << endl;
        }
    };
    
    class Tank99:public Tank
    {
    public:
        void message()
        {
            cout << "Tank99" << endl;
        }
    };
    
    //抽象工廠角色
    class TankFactory
    {
    public:
        virtual Tank* createTank() = 0;
    };
    
    //具體的工廠類
    class Tank80Factory:public TankFactory
    {
    public:
        Tank* createTank()
        {
            return new Tank80();
        }
    };
    
    class Tank99Factory:public TankFactory
    {
    public:
        Tank* createTank()
        {
            return new Tank99();
        }
    };
    
    int main()
    {
        TankFactory* factory80 = new Tank80Factory;
        Tank* tank80 = factory80->createTank();
        tank80->message();
        return 0;
    }
    

抽象工廠模式

  • **抽象工廠模式:**抽象工廠模式是所有形態的工廠模式中最爲抽象和最具一般性的一種形態。抽象工廠模式是指當有多個抽象角色時,使用的一種工廠模式。抽象工廠模式可以向客戶端提供一個接口,使客戶端在不必指定產品的具體的情況下,創建多個產品族中的產品對象。根據里氏替換原則,任何接受父類型的地方,都應當能夠接受子類型。因此,實際上系統所需要的,僅僅是類型與這些抽象產品角色相同的一些實例,而不是這些抽象產品的實例。換言之,也就是這些抽象產品的具體子類的實例。工廠類負責創建抽象產品的具體子類的實例。

  • 產品族

    • 是指位於不同產品等級結構中,功能相關聯的產品組成的家族。一般是位於不同的等級結構中的相同位置上。顯然,每一個產品族中含有產品的數目,與產品等級結構的數目是相等的,形成一個二維的座標系,水平座標是產品等級結構,縱座標是產品族。叫做相圖。
    • 當有多個不同的等級結構的產品時,如果使用工廠方法模式就勢必要使用多個獨立的工廠等級結構來對付這些產品的等級結構。如果這些產品等級結構是平行的,會導致多個平行的工廠等級結構。
    • 抽象工廠模式使用同一個 工廠等級結構負責這些不同產品等級結構產品對象的創建。
    • 對於每一個產品族,都有一個具體工廠。而每一個具體工廠創建屬於同一個產品族,但是分屬於不同等級結構的產品。
    • 通過引進抽象工廠模式,可以處理具有相同(或者相似)等級結構的多個產品族中的產品對象的創建問題。
    • 由於每個具體工廠角色都需要負責兩個不同等級結構的產品對象的創建,因此每個工廠角色都需要提供兩個工廠方法,分別用於創建兩個等級結構的產品。既然每個具體工廠角色都需要實現這兩個工廠方法,所以具有一般性,不妨抽象出來,移動到抽象工廠角色中加以聲明。
  • **常用場景:**一件產品有很多個組件組成,與之類似的產品還有很多。每個產品與組件是一一對應的關係。類如一個藥品公司生產的口服藥劑,現在有A,B,C三種口服藥劑,這三個口服藥劑都有各自的藥水、說明書、包裝盒。A,B,C對應的就是產品族的概念,藥水和說明書,包裝盒就是組件的概念。

  • 代碼: 數據庫訪問程序設計,不同的數據庫訪問方式可能不一樣,爲了抽象對不同數據庫的訪問,可以將數據庫隱藏起來,提供統一的訪問方式,用多態進行實現。

    #include <iostream>
    using namespace std;
    //用戶表接口
    class IUser
    {
    public:
    	virtual void Insert() = 0;
    	virtual void GetUser() = 0;
    };
    //SqlServer數據庫訪問User表
    class SqlServerUser : public IUser
    {
    public:
    	void Insert()
    	{
    		cout << "在SQL Server中給User表增加一條記錄" << endl;
    	}
    	void GetUser()
    	{
    		cout << "在SQL Server中給User表獲取一條記錄" << endl;
    	}
    };
    //Access數據庫訪問User表
    class AccessUser : public IUser
    {
    public:
    	void Insert()
    	{
    		cout << "在Access中給User表增加一條記錄" << endl;
    	}
    	void GetUser()
    	{
    		cout << "在Access中User表獲取一條記錄" << endl;
    	}
    };
    //Department表接口
    class IDepartment
    {
    public:
    	virtual void Insert() = 0;
    	virtual void GetDepartment() = 0;
    };
    //SqlServer數據庫訪問Department表
    class SqlServerDepartment : public IDepartment
    {
    public:
    	void Insert()
    	{
    		cout << "在SQL Server中給Department表增加一條記錄" << endl;
    	}
    	void GetDepartment()
    	{
    		cout << "在SQL Server中Department獲取一條記錄" << endl;
    	};
    };
    //Access數據庫訪問Department表
    class AccessDepartment : public IDepartment
    {
    public:
    	void Insert()
    	{
    		cout << "在Access中給Department表增加一條記錄" << endl;
    	}
    	void GetDepartment()
    	{
    		cout << "在Access中Department獲取一條記錄" << endl;
    	};
    };
    //抽象工廠接口
    class IFactory
    {
    public:
    	virtual IUser* CreateUser() = 0;
    	virtual IDepartment* CreateDepartment() = 0;
    };
    //SqlServer工廠實現
    class SqlServerFactory : public IFactory
    {
    	IUser* CreateUser()
    	{
    		return new SqlServerUser();
    	}
    	IDepartment* CreateDepartment()
    	{
    		return new SqlServerDepartment();
    	}
    };
    //Access工廠實現
    class AccessFactory : public IFactory
    {
    	IUser* CreateUser()
    	{
    		return new AccessUser();
    	}
    	IDepartment* CreateDepartment()
    	{
    		return new AccessDepartment();
    	}
    };
    int main()
    {
    	//創建工廠
    	IFactory * pFactory = NULL;
    	IUser * pUser = NULL;
    	IDepartment * pDepartment = NULL;
    	int choise;
    	cout << "選擇數據庫: ";
    	cin >> choise;
    	switch (choise)
    	{
    	case 1:
    		pFactory = new SqlServerFactory(); //創建SqlServer訪問的工廠
    		break;
    	case 2:
    		pFactory = new AccessFactory(); //創建Access訪問的工廠
    		break;
    	}
    	//一致的操作
    	pUser = pFactory->CreateUser();
    	pDepartment = pFactory->CreateDepartment();
    	pUser->Insert();
    	pUser->GetUser();
    	pDepartment->Insert();
    	pDepartment->GetDepartment();
    	return 0;
    }
    
    

    版權申明:未經博主同意,禁止轉載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章