程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++設計形式之建造者形式

C++設計形式之建造者形式

編輯:關於C++

C++設計形式之建造者形式。本站提示廣大學習愛好者:(C++設計形式之建造者形式)文章只能為提供參考,不一定能成為您想要的結果。以下是C++設計形式之建造者形式正文


建造者形式

在GOF的《設計形式 可復用面向對象軟件的基本》中是如許說的:將一個龐雜對象的構建與它的表現分別,使得異樣的構建進程可以創立分歧的表現。

這句話,似懂非懂的。一個龐雜對象的創立,其平日是由許多的子對象組成;假如一個對象可以或許直接就創立好了,那末也不會稱之為龐雜對象。因為項目中需求的變更,這個龐雜對象的各個部門常常會產生激烈的變更,然則,不論怎樣變更,將它們組合在一路,構成一個龐雜的對象的現實是不會變的。建造者形式就供給了一種“封裝機制”來將各個對象的變更隔分開,終究,組分解龐雜對象的進程是不會變的。

在《年夜話設計形式》一書中,例舉了一個很好的例子————建造君子。建造一個君子,要分為六步:頭部、身材、左手、右手、左腳和右腳。與籠統工場形式分歧的是,建造者形式是在Director的掌握下一步一步的結構出來的,在建造的進程中,建造者形式可以停止更精致的掌握。不論人的頭部、身材、左手、右手、左腳或許右腳若何變更,然則終究照樣由這幾部門組合在一路構成一小我,固然是統一個建造進程,然則這小我就會有分歧的表現,好比,瘦子,胖子,個高的,個低的等等。

UML圖

類圖以下:

時序圖以下:

代碼完成


/*
** FileName     : BuilderPattern
** Author       : Jelly Young
** Date         : 2013/11/22
** Description  : More information, please go to http://www.jb51.net
*/
 
#include <iostream>
using namespace std;
 
typedef enum MANTYPETag
{
    kFatMan,
    kThinMan,
    kNormal
}MANTYPE;
 
class Man
{
public:
    void SetHead(MANTYPE type){ m_Type = type; }
    void SetBody(MANTYPE type){ m_Type = type; }
    void SetLeftHand(MANTYPE type){ m_Type = type; }
    void SetRightHand(MANTYPE type){ m_Type = type; }
    void SetLeftFoot(MANTYPE type){ m_Type = type; }
    void SetRightFoot(MANTYPE type){ m_Type = type; }
    void ShowMan()
    {
        switch (m_Type)
        {
        case kFatMan:
            cout<<"I'm a fat man"<<endl;
            return;
 
        case kThinMan:
            cout<<"I'm a thin man"<<endl;
            return;
 
        default:
            cout<<"I'm a normal man"<<endl;
            return;
        }
    }
 
private:
    MANTYPE m_Type;
};
 
// Builder
class Builder
{
public:
    virtual void BuildHead(){}
    virtual void BuildBody(){}
    virtual void BuildLeftHand(){}
    virtual void BuildRightHand(){}
    virtual void BuildLeftFoot(){}
    virtual void BuildRightFoot(){}
    virtual Man *GetMan(){ return NULL; }
};
 
// FatManBuilder
class FatManBuilder : public Builder
{
public:
    FatManBuilder(){ m_FatMan = new Man(); }
    void BuildHead(){ m_FatMan->SetHead(kFatMan); }
    void BuildBody(){ m_FatMan->SetBody(kFatMan); }
    void BuildLeftHand(){ m_FatMan->SetLeftHand(kFatMan); }
    void BuildRightHand(){ m_FatMan->SetRightHand(kFatMan); }
    void BuildLeftFoot(){ m_FatMan->SetLeftFoot(kFatMan); }
    void BuildRightFoot(){ m_FatMan->SetRightFoot(kFatMan); }
    Man *GetMan(){ return m_FatMan; }
 
private:
    Man *m_FatMan;
};
 
// ThisManBuilder
class ThinManBuilder : public Builder
{
public:
    ThinManBuilder(){ m_ThinMan = new Man(); }
    void BuildHead(){ m_ThinMan->SetHead(kThinMan); }
    void BuildBody(){ m_ThinMan->SetBody(kThinMan); }
    void BuildLeftHand(){ m_ThinMan->SetLeftHand(kThinMan); }
    void BuildRightHand(){ m_ThinMan->SetRightHand(kThinMan); }
    void BuildLeftFoot(){ m_ThinMan->SetLeftFoot(kThinMan); }
    void BuildRightFoot(){ m_ThinMan->SetRightFoot(kThinMan); }
    Man *GetMan(){ return m_ThinMan; }
 
private:
    Man *m_ThinMan;
};
 
// Director
class Director
{
public:
    Director(Builder *builder) { m_Builder = builder; }
    void CreateMan();
 
private:
    Builder *m_Builder;
};
 
void Director::CreateMan()
{
    m_Builder->BuildHead();
    m_Builder->BuildBody();
    m_Builder->BuildLeftHand();
    m_Builder->BuildRightHand();
    m_Builder->BuildLeftHand();
    m_Builder->BuildRightHand();
}
 
int main(int argc, char *argv[])
{
    Builder *builderObj = new FatManBuilder();
    Director directorObj(builderObj);
    directorObj.CreateMan();
    Man *manObj = builderObj->GetMan();
    if (manObj == NULL)
        return 0;
 
    manObj->ShowMan();
    delete builderObj;
    builderObj = NULL;
 
    return 0;
};

下面這個例子比擬雜,然則也是建造者形式的運用。上面這個例子是建造者最普通,最簡略的完成辦法:


/*
** FileName     : BuilderPattern
** Author       : Jelly Young
** Date         : 2013/11/23
** Description  : More information, please go to http://www.jb51.net
*/
 
#include <iostream>
#include <vector>
using namespace std;
 
class Builder;
 
// Product
class Product
{
public:
    void AddPart(const char *info) { m_PartInfoVec.push_back(info); }
    void ShowProduct()
    {
        for (std::vector<const char *>::iterator item = m_PartInfoVec.begin();
            item != m_PartInfoVec.end(); ++item)
        {
            cout<<*item<<endl;
        }
    }
 
private:
    std::vector<const char *> m_PartInfoVec;
};
 
// Builder
class Builder
{
public:
    virtual void BuildPartA() {}
    virtual void BuildPartB() {}
    virtual Product *GetProduct() { return NULL; }
};
 
// ConcreteBuilder
class ConcreteBuilder : public Builder
{
public:
    ConcreteBuilder() { m_Product = new Product(); }
    void BuildPartA()
    {
        m_Product->AddPart("PartA completed");
    }
 
    void BuildPartB()
    {
        m_Product->AddPart("PartB completed");
    }
 
    Product *GetProduct() { return m_Product; }
 
private:
    Product *m_Product;
};
 
// Director
class Director
{
public:
    Director(Builder *builder) { m_Builder = builder; }
    void CreateProduct()
    {
        m_Builder->BuildPartA();
        m_Builder->BuildPartB();
    }
 
private:
    Builder *m_Builder;
};
 
// main
int main()
{
    Builder *builderObj = new ConcreteBuilder();
    Director directorObj(builderObj);
    directorObj.CreateProduct();
    Product *productObj = builderObj->GetProduct();
    if (productObj == NULL)
    {
        return 0;
    }
    productObj->ShowProduct();
    delete builderObj;
    builderObj = NULL;
}

經由過程比擬下面的兩個例子,可以很輕易的把建造者形式的骨架籠統出來。

應用要點

1.建造者形式生成的對象有龐雜的外部構造,將分步調的去構建一個龐雜的對象,分若干步是肯定的,而每步的完成是分歧的,能夠常常產生變更;

2.在下面的例子中,我們都看到了終究生成的Man和Product都沒有籠統類,這又導出建造者實用的一種情形,當須要創立龐雜對象的進程中,龐雜對象沒有若干配合的特色,很難籠統出來時,而龐雜對象的組裝又有必定的類似點時,建造者形式便可以施展出感化。簡略的說,能夠應用了建造者形式,終究建造的對象能夠沒有多年夜的關系,關於這一點,浏覽《設計形式 可復用面向對象軟件的基本》中的建造者形式時是最有領會的。

總結

一個龐雜對象是由多個部件構成的,建造者形式是把龐雜對象的創立和部件的創立分離開來,分離用Builder類和Director類來表現。用Director構建最初的龐雜對象,而在下面Builder接口中封裝的是若何創立一個個部件(龐雜對象是由這些部件構成的),也就是說,Director擔任若何將部件最初組裝成產物。如許建造者形式就讓設計和完成解耦了。

剛開端接觸建造者形式的時刻,最輕易把建造者和籠統工場形式混雜了。因為而這都屬於創立型的設計形式,所以兩者之間是有公共點的,然則建造者形式重視於對象組合,即分歧的小對象構成一個全體的龐雜年夜對象,而籠統工場形式針關於接口編程,只是對外供給創立對象的工場接口,不擔任對象以後的處置。

建造者形式,是一個比擬龐雜,不輕易衡量的設計形式。年夜家應當更多的浏覽開源代碼,懂得別人是若何應用該形式的。從現實的運用中進修設計形式。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved