設計模式--工廠模式


一。簡單工廠模式
首先將需要創建的各種不同對象的相關代碼封裝到不同的類中,這些類稱爲具體產品類,
而將它們公共的代碼進行抽象和提取後封裝在一個抽象產品類中,每一個具體產品類都是抽象產品類的子類;
然後提供一個工廠類用於創建各種產品,在工廠類中提供一個創建產品的工廠方法,
該方法可以根據所傳入的參數不同創建不同的具體產品對象;客戶端只需調用工廠類的工廠方法並傳入相應的參數即可得到一個產品對象。

簡單工廠模式(Simple Factory Pattern):定義一個工廠類,它可以根據參數的不同返回不同類的實例,被創建的實例通常都具有共同的父類。
因爲在簡單工廠模式中用於創建實例的方法是靜態(static)方法,因此簡單工廠模式又被稱爲靜態工廠方法(Static Factory Method)模式,
它屬於類創建型模式。

 簡單工廠模式的要點在於:當你需要什麼,只需要傳入一個正確的參數,就可以獲取你所需要的對象,
 而無須知道其創建細節。簡單工廠模式結構比較簡單,其核心是工廠類的設計

 使用模式的實現方式

 ====================================================================================
     軟件產品類的實現代碼如下:
#include <iostream>  
using namespace std;  
//抽象軟件產品類  
class SoftProduct  
{  
public:  
    virtual void DisplayProduct() = 0;  
};  


//銀行卡產品  
class BankCard : public SoftProduct  
{  
public:  
    void DisplayProduct()  
    {  
        cout << "項目名稱: " << "銀行卡識別項目" << endl;  
    }  
};  



//身份證產品  
class IdentityCard : public SoftProduct  
{  
public:  
    void DisplayProduct()  
    {  
        cout << "項目名稱: " << "身份證識別項目" << endl;  
    }  
};  




//駕駛證產品  
class DriveLicense : public SoftProduct  
{  
public:  
    void DisplayProduct()  
    {  
        cout << "項目名稱: " << "駕駛證識別項目" << endl;  
    }  
};  


#endif  

======================================================================
 產品工廠的實現代碼如下:
#ifndef _PRODUCT_FACTORY_H_  
#define _PRODUCT_FACTORY_H_  

#include <iostream>  
#include <string>  
#include "SoftProduct.h"  

using namespace std;  


//產品工廠  
class ProductFactory  
{  

public:  
    //靜態方法,根據類型創建具體產品  
    static SoftProduct * CreateProduct(string strProductName)  
    {  
        SoftProduct * pSoftProduct = NULL;  

        if( 0 == strcmp(strProductName.c_str(), "銀行卡識別項目") )  
        {  
            pSoftProduct = new BankCard();  
        }  
        else if( 0 == strcmp(strProductName.c_str(), "身份證識別項目") )  
        {  
            pSoftProduct = new IdentityCard();  
        }  
        else if( 0 == strcmp(strProductName.c_str(), "駕駛證識別項目") )  
        {  
            pSoftProduct = new DriveLicense();  
        }  
        return pSoftProduct;  
    }  
};  
================================================
測試程序實現代碼如下:
#include <iostream>  
#include "SoftProduct.h"  
#include "ProductFactory.h"  
using namespace std;  

int main()  
{  
    SoftProduct * pSoftProduct = NULL;  

    //創建銀行卡識別項目  
    pSoftProduct = ProductFactory::CreateProduct("銀行卡識別項目");  
    pSoftProduct->DisplayProduct();  
    delete pSoftProduct;  
    pSoftProduct = NULL;  

    //創建身份證識別項目  
    pSoftProduct = ProductFactory::CreateProduct("身份證識別項目");  
    pSoftProduct->DisplayProduct();  
    delete pSoftProduct;  
    pSoftProduct = NULL;  

    //創建駕駛證識別項目  
    pSoftProduct = ProductFactory::CreateProduct("駕駛證識別項目");  
    pSoftProduct->DisplayProduct();  
    delete pSoftProduct;  
    pSoftProduct = NULL;  

    return 0;  
}  

添加了一個產品工廠類ProductFactory,該類有一個靜態CreateProduct方法,根據參數類型的不同創建不同的具體軟件項目產品。
CreateProduct內部封裝了具體對象的創建細節,對客戶端而言,不再需要具體的對象類型了,客戶端完全針對接口進行編程,
對客戶端隱藏了對象創建的細節。

簡單工廠模式提供了專門的工廠類用於創建對象,將對象的創建和對象的使用分離開,它作爲一種最簡單的工廠模式在軟件開發中得到了較爲廣泛的應用。
1.主要優點
    簡單工廠模式的主要優點如下:
    (1) 工廠類包含必要的判斷邏輯,可以決定在什麼時候創建哪一個產品類的實例,客戶端可以免除直接創建產品對象的職責,
        而僅僅“消費”產品,簡單工廠模式實現了對象創建和使用的分離。也就是說工廠類封裝了變化,封裝了對象創建的具體細節,
        對客戶端隱藏對象創建的細節,使得客戶類針對接口進行編程。滿足"針對接口編程而不是針對具體編程原則"。
    (2) 客戶端無須知道所創建的具體產品類的類名,只需要知道具體產品類所對應的參數即可,對於一些複雜的類名,
        通過簡單工廠模式可以在一定程度減少使用者的記憶量。滿足"迪米特法則,也就是和直接朋友通信原則"。
    (3) 具體對象創建是一個變化過程,因此把對象的創建封裝起來,體現了"封裝變化原則"2.主要缺點
    簡單工廠模式的主要缺點如下:
    (1)  由於工廠類集中了所有產品的創建邏輯,職責過重,一旦不能正常工作,整個系統都要受到影響,違背"單一原則"。
    (2) 使用簡單工廠模式勢必會增加系統中類的個數(引入了新的工廠類),增加了系統的複雜度和理解難度。
    (3) 系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,在產品類型較多時,有可能造成工廠邏輯過於複雜,
        不利於系統的擴展和維護。違背"開發封閉原則"。
    (4) 簡單工廠模式由於使用了靜態工廠方法,造成工廠角色無法形成基於繼承的等級結




=====================================設計模式============================================
C++設計模式——工廠方法及工廠方法的隱藏實現

在工廠方法模式中,我們不再提供一個統一的工廠類來創建所有的產品對象,
而是針對不同的產品提供不同的工廠,系統提供一個與產品等級結構對應的工廠等級結構。工廠方法模式定義如下:

工廠方法模式(Factory Method Pattern):定義一個用於創建對象的接口,讓子類決定將哪一個類實例化。
工廠方法模式讓一個類的實例化延遲到其子類。工廠方法模式又簡稱爲工廠模式(Factory Pattern),是一種類創建型模式。

Product(抽象產品):它是定義產品的接口,是工廠方法模式所創建對象的超類型,也就是產品對象的公共父類。
ConcreteProduct(具體產品):它實現了抽象產品接口,某種類型的具體產品由專門的具體工廠創建,具體工廠和具體產品之間一一對應。
Factory(抽象工廠):在抽象工廠類中,聲明瞭工廠方法(Factory Method),用於返回一個產品。抽象工廠是工廠方法模式的核心,
                     所有創建對象的工廠類都必須實現該接口。
ConcreteFactory(具體工廠):它是抽象工廠類的子類,實現了抽象工廠中定義的工廠方法,並可由客戶端調用,返回一個具體產品類的實例。

==========================================================================
QQ空間背景風格的設計與實現

2.1背景風格類

 BackgroundStyle背景風格抽象類是抽象的產品類,提供了一個DisplayStyle方法,顯示具體的QQ背景風格。
 ClassicalStyle古典風格背景類、FashionStyle潮流風格背景類、ArtStyle藝術風格背景類是具體的產品類。
---------------------------------------------------------------------------------
[cpp] view plain copy
#ifndef _BACKGROUND_STYLE_H_  
#define _BACKGROUND_STYLE_H_  
#include <iostream>  
#include <string>  
using namespace std;  

//背景風格抽象類  
class BackgroundStyle  
{  
public:  
    //虛方法,顯示背景風格  
    virtual void DisplayStyle() = 0;  
};  


//古典風格背景類  
class ClassicalStyle : public BackgroundStyle  
{  
public:  
    void DisplayStyle()  
    {  
        cout << "古典風格背景" << endl;  
    }  
};  


//潮流風格背景類  
class FashionStyle : public BackgroundStyle  
{  
public:  
    void DisplayStyle()  
    {  
        cout << "潮流風格背景" << endl;  
    }  
};  


//藝術風格背景類  
class ArtStyle : public BackgroundStyle  
{  
public:  
    void DisplayStyle()  
    {  
        cout << "藝術風格背景" << endl;  
    }  
};  

#endif
---------------------------------------------------------------------------------------
2.2 背景風格工廠
 背景風格工廠類實現代碼如下:
[cpp] view plain copy
#ifndef _STYLE_FACTORY_H_  
#define _STYLE_FACTORY_H_  
#include "backgroundStyle.h"  

//背景風格抽象工廠  
class StyleFactory  
{  
public:  
    //工廠方法,具體背景風格由子類完成創建操作  
    virtual BackgroundStyle * CreateBackGroundStyle() = 0;  
};  


//古典風格工廠  
class ClassicalStyleFactory : public StyleFactory  
{  
public:  
    BackgroundStyle * CreateBackGroundStyle()  
    {  
        BackgroundStyle * pClassicalStyle = new ClassicalStyle();  

        return pClassicalStyle;  
    }  
};  


//潮流風格工廠  
class FashionStyleFactory : public StyleFactory  
{  
public:  
    BackgroundStyle * CreateBackGroundStyle()  
    {  
        BackgroundStyle * pFashionStyle = new FashionStyle();  

        return pFashionStyle;  
    }  
};  


//藝術風格工廠  
class ArtStyleFactory : public StyleFactory  
{  
public:  
    BackgroundStyle * CreateBackGroundStyle()  
    {  
        BackgroundStyle * pArtStyle = new ArtStyle();  

        return pArtStyle;  
    }  
};   
#endif  
---------------------------------------------------------------------
4.1. 主要優點
    工廠方法模式的主要優點如下:
    (1) 在工廠方法模式中,工廠方法用來創建客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被實例化這一細節,
        用戶只需要關心所需產品對應的工廠,無須關心創建細節,甚至無須知道具體產品類的類名。也就是說工廠方法模式封裝了變化,
        封裝了對象創建的具體細節,符合"封裝變化原則"。
    (2) 每一個具體工廠只負責創建一個對應的產品,符合"單一原則"。
    (3) 使用工廠方法模式的另一個優點是在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的接口,無須修改客戶端,
        也無須修改其他的具體工廠和具體產品,而只要添加一個具體工廠和具體產品就可以了,這樣,系統的可擴展性也就變得非常好,
        完全符合“開閉原則”。
    (4)客戶端只需要認識抽象的產品類,無需認識具體產品類,降低了客戶端和具體產品類的耦合度。
        也就是說客戶端針對接口進行編程,符合"針對接口進行編程而不是針對具體進行編程原則"4.2. 主要缺點
    工廠方法模式的主要缺點如下:
    (1) 在添加新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,
        系統中類的個數將成對增加,在一定程度上增加了系統的複雜度,有更多的類需要編譯和運行,會給系統帶來一些額外的開銷。

=====================================設計模式============================================
C++設計模式--抽象工廠模式

抽象工廠模式是所有形式的工廠模式中最爲抽象和最具一般性的一種形式。抽象工廠模式與工廠方法模式最大的區別在於,
工廠方法模式針對的是一個產品等級結構,而抽象工廠模式需要面對多個產品等級結構,
一個工廠等級結構可以負責多個不同產品等級結構中的產品對象的創建。
當一個工廠等級結構可以創建出分屬於不同產品等級結構的一個產品族中的所有對象時,抽象工廠模式比工廠方法模式更爲簡單、更有效率

  抽象工廠模式爲創建一組對象提供了一種解決方案。
  與工廠方法模式相比,抽象工廠模式中的具體工廠不只是創建一種產品,它負責創建一族產品。抽象工廠模式定義如下:
  抽象工廠模式(Abstract Factory Pattern):提供一個創建一系列相關或相互依賴對象的接口,而無須指定它們具體的類。它是一種對象創建型模式。

AbstractFactory(抽象工廠):它聲明瞭一組用於創建一族產品的工廠方法,每一個工廠方法對應一種產品。
    這些產品可以沒有任何的聯繫,但這些產品可以組合起來,可以構成一個產品族。
ConcreteFactory(具體工廠):它實現了在抽象工廠中聲明的創建產品的工廠方法,生成一組具體產品,
    這些產品構成了一個產品族,每一個產品都位於某個產品等級結構中。
AbstractProduct(抽象產品):它爲每種產品聲明接口,在抽象產品中聲明瞭產品所具有的業務方法。
ConcreteProduct(具體產品):它定義具體工廠生產的具體產品對象,實現抽象產品接口中聲明的業務方法。

5、抽象工廠模式總結

       簡單工廠模式和工廠方法模式都只產生一種類型的產品對象。然而在抽象工廠模式中,每一個具體工廠都提供了多個工廠方法用於產生多種不同類型的產品,
       這些產品可以沒有任何的聯繫,位於不同的產品等級,但這些產品可以組合起來,構成一個產品族。抽象工廠模式是工廠方法模式的進一步延伸,
       由於它提供了功能更爲強大的工廠類並且具備較好的可擴展性,在軟件開發中得以廣泛應用。使用抽象工廠模式來實現在不同的操作系統中應用程序呈現與所在操作系統一致的外觀界面。
5.1.主要優點
    抽象工廠模式的主要優點如下:
    (1) 抽象工廠模式隔離了具體類的生成,使得客戶並不需要知道什麼被創建。由於這種隔離,更換一個具體工廠就變得相對容易,
    所有的具體工廠都實現了抽象工廠中定義的那些公共接口,因此只需改變具體工廠的實例,就可以在某種程度上改變整個軟件系統的行爲。
    抽象工廠封裝了變化,封裝了對象創建的具體細節,對客戶端隱藏對象創建的具體細節,符合"封裝變化原則"。
    (2) 當一個產品族中的多個對象被設計成一起工作時,它能夠保證客戶端始終只使用同一個產品族中的對象。
    (3) 增加新的產品族很方便,無須修改已有系統,符合“開閉原則”。
    (4) 客戶端可以針對抽象進行編程,而不需要知道具體類型,符合"針對接口進行編程而不是針對具體進行編程原則"5.2.主要缺點
    抽象工廠模式的主要缺點如下:
    增加新的產品等級結構麻煩,需要對原有系統進行較大的修改,甚至需要修改抽象層代碼,這顯然會帶來較大的不便,違背了“開閉原則


=====================================設計模式============================================
C++設計模式——建造者模式

建造者模式(Builder Pattern):將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。建造者模式是一種對象創建型模式。

Builder(抽象建造者):它爲創建一個產品Product對象的各個部件指定抽象接口,在該接口中一般聲明兩類方法,
        一類方法是buildPartX(),它們用於創建複雜對象的各個部件;
        另一類方法是getResult(),它們用於返回複雜對象。Builder既可以是抽象類,也可以是接口。
ConcreteBuilder(具體建造者):它實現了Builder接口,實現各個部件的具體構造和裝配方法,定義並明確它所創建的複雜對象, 也可以提供一個方法返回創建好的複雜產品對象。
Product(產品角色):它是被構建的複雜對象,包含多個組成部件,具體建造者創建該產品的內部表示並定義它的裝配過程。
Director(指揮者):指揮者又稱爲導演類,它負責安排複雜對象的建造次序,指揮者與抽象建造者之間存在關聯關係,
        可以在其construct()建造方法中調用建造者對象的部件構造與裝配方法,完成複雜對象的建造。
        客戶端一般只需要與指揮者進行交互,在客戶端確定具體建造者的類型,並實例化具體建造者對象,
        然後通過指揮者類的構造函數或者Setter方法將該對象傳入指揮者類中。


播放器
--------------------------------------------------------------------------------------------------
    暴風影音播放器.h頭文件代碼如下:------------具體建造者
[cpp] view plain copy
<pre name="code" class="cpp">#ifndef _PLAYER_H_  
#define _PLAYER_H_  
#include <iostream>  
#include <string>  
using namespace std;  

//播放器  
class Player  
{  
private:  
    string m_strMenu;           //菜單欄  
    string m_strWindow;         //主窗口  
    string m_strPlayList;           //播放列表  
    string m_strControlBar;         //進度條  
    string m_strCollectList;        //收藏列表  
public:  
    //設置部件  
    void SetMenu(string strMenu);  
    void SetWindow(string strWindow);  
    void SetPlayList(string strPlayList);  
    void SetControlBar(string strControlBar);  
    void SetCollectList(string strCollectList);  

    //獲取各部件  
    string GetMenu();  
    string GetWindow();  
    string GetPlayList();  
    string GetControlBar();  
    string GetCollectList();  

    //顯示播放器窗口包含的部件  
    void Display();  
};  

#endif  
----------------------------------------------------------------------------
暴風影響播放器Cpp文件代碼如下:

[cpp] view plain copy
#include "Player.h"  

//設置主菜單部件  
void Player::SetMenu(string strMenu)  
{  
    m_strMenu = strMenu;  
}  

//設置主窗口部件  
void Player::SetWindow(string strWindow)  
{  
    m_strWindow = strWindow;  
}  

//設計播放列表部件  
void Player::SetPlayList(string strPlayList)  
{  
    m_strPlayList = strPlayList;  
}  

//設置滾動條部件  
void Player::SetControlBar(string strControlBar)  
{  
    m_strControlBar = strControlBar;  
}  

//設置收藏列表部件  
void Player::SetCollectList(string strCollectList)  
{  
    m_strCollectList = strCollectList;  
}  

//獲取主菜單部件  
string Player::GetMenu()  
{  
    return m_strMenu;  
}  

//獲取主窗口部件  
string Player::GetWindow()  
{  
    return m_strWindow;  
}  

//獲取播放列表部件  
string Player::GetPlayList()  
{  
    return m_strPlayList;  
}  

//獲取滾動條部件  
string Player::GetControlBar()  
{  
    return m_strControlBar;  
}  


//獲取收藏列表部件  
string Player::GetCollectList()  
{  
    return m_strCollectList;  
}  

//顯示播放器窗口包含的部件  
void Player::Display()  
{  
    cout << "---" << m_strWindow << endl;  
    cout << "---" << m_strMenu << endl;  
    cout << "---" << m_strPlayList << endl;  
    cout << "---" << m_strControlBar << endl;  
    cout << "---" << m_strCollectList << endl << endl;  
}  

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