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

C++Builder建造者模式詳解

編輯:關於C++

生活中有著很多的Builder的例子,個人覺得大學生活就是一個Builder模式的最好體驗:要完成大學教育,一般將大學教育過程分成4個學期進行,因此沒有學習可以看作是構建完整大學教育的一個部分構建過程,每個人經過這4年的(4個階段)構建過程得到的最後的結果不一樣,因為可能在四個階段的構建中引入了很多的參數(每個人的機會和際遇不完全相同)。

Builder模式要解決的也正是這樣的問題:當我們要創建的對象很復雜的時候(通常是由很多其他的對象組合而成),我們要要復雜對象的創建過程和這個對象的表示(展示)分離開來,這樣做的好處就是通過一步步的進行復雜對象的構建,由於在每一步的構造過程中可以引入參數,使得經過相同的步驟創建最後得到的對象的展示不一樣。

Builder模式的UML結構圖如圖1所示:

\

  Builder模式的關鍵是其中的Director對象並不直接返回對象,而是通過一步步(BuildPartA,BuildPartB,BuildPartC)來一步步進行對象的創建。當然這裡Director可以提供一個默認的返回對象的接口(即返回通用的復雜對象的創建,即不指定或者特定唯一指定BuildPart中的參數)。

  Builder模式的實現基於以下幾個面向對象的設計原則:

  1)把變化的部分提取出來形成一個基類和對應的接口函數,在這裡不會變化的是都會創建PartA和PartB,變化的則是不同的創建方法,於是就抽取出這裡的Builder基類和BuildPartA,BuildPartB接口函數

  2)采用聚合的方式聚合了會發生變化的基類,就是這裡Director聚合了Builder類的指針.

  以上,通過兩個派生類ConcreteBuilder1、ConcreteBuilder2定義了兩種不同的建造細節(建造步驟是一樣的,由Construct函數確定),通過兩個派生類所建造出來的對象,對外部所展現出來的屬性或者功能是不一樣的,由各自Builder派生類中的建造方法(BuildPartA、BuildPartB、BuildPartC)決定。

Builder.h

 

#ifndef _BUILDER_H_
#define _BUILDER_H_

#include 
#include 

using namespace std;

//產品類
class Product
{
private:
    string m_partA;
    string m_partB;
    string m_partC;
public:
    void setPartA(const string& s);
    void setPartB(const string& s);
    void setPartC(const string& s);
    Product();
    ~Product();
};

//抽象Builder基類,定義不同部分的創建接口
class Builder
{
public:
    virtual void BuildPartA()=0;
    virtual void BuildPartB()=0;
    virtual void BuildPartC()=0;
    virtual Product* GetProduct()=0;
    Builder();
    virtual ~Builder();
};

//  Builder的派生類,實現BuilderPartA和BuilderPartB和BuildPartC接口函數 
class ConcreteBuilder1:public Builder
{
public:
    ConcreteBuilder1();
    ~ConcreteBuilder1();
    virtual void BuildPartA();
    virtual void BuildPartB();
    virtual void BuildPartC();
    virtual Product* GetProduct();
private:
    Product* m_pProduct;
};

//  Builder的派生類,實現BuilderPartA和BuilderPartB和BuildPartC接口函數 
class ConcreteBuilder2:public Builder
{
public:
    ConcreteBuilder2();
    ~ConcreteBuilder2();
    virtual void BuildPartA();
    virtual void BuildPartB();
    virtual void BuildPartC();
    virtual Product* GetProduct();
private:
    Product* m_pProduct;
};

//ConcreteBuilder1與ConcreteBuilder2是Builder的兩個派生類,用於實現兩種不同的建造細節

 // 使用Builder構建產品,構建產品的過程都一致,但是不同的builder有不同的實現
 // 這個不同的實現通過不同的Builder派生類來實現,存有一個Builder的指針,通過這個來實現多態調用 
class Director
{
public:
    Director(Builder* pBuilder);
    ~Director();

    //Construct函數定義一個對象的整個構建過程,不同的部分之間的裝配方式都是一致的,
    //首先構建PartA其次是PartB,只是根據不同的構建者會有不同的表示 
    void Construct();
    //void Construct(const string& buildPara);
private:
    Builder* m_pBuilder;
};

#endif

 

Director.cpp

 

#include "Builder.h"
#include 
#include 

using namespace std;

Product::~Product()
{
}

Product::Product()
{}

void Product::setPartA(const string& s)
{
    this->m_partA = s;
}

void Product::setPartB(const string& s)
{
    this->m_partB = s;
}

void Product::setPartC(const string& s)
{
    this->m_partC = s;
}

Builder::Builder()
{}

Builder::~Builder()
{}

ConcreteBuilder1::ConcreteBuilder1()
{
    this->m_pProduct = new Product();
    cout<<"Create empty product!"<m_pProduct->setPartA("A");
    cout<<"BuildPartA"<m_pProduct->setPartB("B");
    cout<<"BuildPartB"<m_pProduct->setPartC("C");
    cout<<"BuildPartC"<m_pProduct;
}

ConcreteBuilder1::~ConcreteBuilder1()
{
    delete this->m_pProduct;
    this->m_pProduct = NULL;
}

ConcreteBuilder2::ConcreteBuilder2()
{
    this->m_pProduct = new Product();
    cout<<"Create empty product!"<m_pProduct->setPartA("A");
    cout<<"BuildPartA"<m_pProduct->setPartB("B");
    cout<<"BuildPartB"<m_pProduct->setPartC("C");
    cout<<"BuildPartC"<m_pProduct;
}

ConcreteBuilder2::~ConcreteBuilder2()
{
    delete this->m_pProduct;
    this->m_pProduct = NULL;
}

Director::Director(Builder* pBuilder)
{
    this->m_pBuilder = pBuilder;
}

void Director::Construct()
{
    this->m_pBuilder->BuildPartA();
    this->m_pBuilder->BuildPartB();
    this->m_pBuilder->BuildPartC();
}

Director::~Director()
{
    delete this->m_pBuilder;
    this->m_pBuilder = NULL;
}
main.cpp

 

 

#include "Builder.h"
#include 

using namespace std;

int main()
{
    Director* pDirector = new Director(new ConcreteBuilder1());
    pDirector->Construct();

    Director* pDirector1 = new Director(new ConcreteBuilder2());
    pDirector1->Construct();

    return 0;
}

建造者模式和工廠模式使用很相似,但也有區別:

 

 

建造者模式最主要功能是基本方法的調用順序安排,也就是這些基本方法已經實現了;而工廠方法則重點是創建,你要什麼對象我創造一個對象出來,組裝順序則不是他關心的。

建造者模式使用的場景,一是產品類非常的復雜,或者產品類中的調用順序不同產生了不同的效能,這個時候使用建造者模式是非常合適。




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