03:建造者模式——C++實現
目錄
一、介紹
建造者模式(Builder Pattern)使用多個簡單的物件一步一步構建成一個複雜的物件。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。將一個複雜的構建與其表示相分離,使得同樣的構建過程可以建立不同的表示。
二、應用場景
1、需要生成的物件具有複雜的內部結構。
2、需要生成的物件內部屬性本身相互依賴。
一些基本部件不會變,而其組合經常變化的時候。
如:在肯德基,漢堡、可樂、薯條、炸雞翅等是不變的,而其組合是經常變化的,生成出所謂的"套餐"。
三、要點
將變與不變分離開。
Builder(抽象建造者):為建立一個產品物件的各個部件指定抽象介面。
ConcreteBuilder(具體建造者):實現 Builder 的介面以構造和裝配該產品的各個部件,定義並明確它所建立的表示,並提供一個檢索產品的介面。
Director(指揮者):構造一個使用 Builder 介面的物件。
Product(產品):表示被構造的複雜物件。ConcreteBuilder 建立該產品的內部表示並定義它的裝配過程,包含定義組成部件的類,包括將這些部件裝配成最終產品的介面。
四、樣例
1、建立產品
// product.h #ifndef PRODUCT_H #define PRODUCT_H #include <iostream> #include <string> using namespace std; // computer class Computer { public: void SetmCpu(string cpu) { m_strCpu = cpu; } void SetMainBoard(string mainboard) { m_strMainBoard = mainboard; } void SetRam(string ram) { m_strRam = ram; } void SetVideoCard(string videoCard) { m_strVideoCard = videoCard; } string GetCpu() { return m_strCpu; } string GetMainBoard() { return m_strMainBoard; } string GetRam() { return m_strMainBoard; } string GetVideoCard() { return m_strVideoCard; } private: string m_strCpu; // CPU string m_strMainBoard; string m_strRam; string m_strVideoCard; }; #endif
2、建立抽象建造者:產品類準備好就可以建立Builder類了,它提供的功能用於建立電腦各個部件。
// builder.h
#ifndef BUILDER_H
#define BUILDER_H
#include "product.h"
// 建造者介面,組裝流程
class IBuilder
{
public:
virtual void BuildCpu() = 0;
virtual void BuildMainBoard() = 0;
virtual void BuildRam() = 0;
virtual void BuildVideoCard() = 0;
virtual Computer* GetResult() = 0; // 獲取建造後產品
};
#endif
3、建立具體建造者:有了 Builder 介面,接下來的事情就是讓 ConcreteBuilder 物件到位。在這些建造者中,我們可以指定每臺電腦要使用的部件資訊。
// concrete_builder.h
#ifndef CONCRETE_BUILDER_H
#define CONCRETE_BUILDER_H
#include "builder.h"
// ThinkPad系列
class ThinkPadBuilder : public IBuilder
{
public:
ThinkPadBuilder() { m_pComputer = new Computer(); }
void BuildCpu() { m_pComputer->SetmCpu("i5-6200U"); }
void BuildMainBoard() { m_pComputer->SetMainBoard("Intel DH57DD"); }
void BuildRam() { m_pComputer->SetRam("DDR4"); }
void BuildVideoCard() { m_pComputer->SetVideoCard("NVDIA Geforce 920MX"); }
Computer* GetResult() { return m_pComputer; }
private:
Computer *m_pComputer;
};
// Yoga系列
class YogaBuilder : public IBuilder
{
public:
YogaBuilder() { m_pComputer = new Computer(); }
void BuildCpu() { m_pComputer->SetmCpu("i7-7500U"); }
void BuildMainBoard() { m_pComputer->SetMainBoard("Intel DP55KG"); }
void BuildRam() { m_pComputer->SetRam("DDR5"); }
void BuildVideoCard() { m_pComputer->SetVideoCard("NVDIA Geforce 940MX"); }
Computer* GetResult() { return m_pComputer; }
private:
Computer *m_pComputer;
};
#endif
4、建立指揮者:建立一個 Director 類,讓 Create 方法接受一個 IBuilder,然後在內部呼叫相應的組裝函式。
// director.h
#ifndef DIRECTOR_H
#define DIRECTOR_H
#include "builder.h"
// 指揮者
class Director
{
public:
void Create(IBuilder *pBuilder)
{
pBuilder->BuildCpu();
pBuilder->BuildMainBoard();
pBuilder->BuildRam();
pBuilder->BuildVideoCard();
}
};
#endif
5、建立客戶端
// main.cpp
#include "concrete_builder.h"
#include "director.h"
#include <string>
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p) { delete (p); (p) = NULL; } }
#endif
int main()
{
Director *pDirector = new Director();
ThinkPadBuilder *pTPBuilder = new ThinkPadBuilder();
YogaBuilder *pYogaBuilder = new YogaBuilder();
// 組裝
pDirector->Create(pTPBuilder);
pDirector->Create(pYogaBuilder);
// 獲取組裝後電腦
Computer *pThinkPadComputer = pTPBuilder->GetResult();
Computer *pYogaComputer = pYogaBuilder->GetResult();
// 測試輸出
cout << "------ThinkPad------" << endl;
cout << "CPU:" << pThinkPadComputer->GetCPU() << endl;
cout << "MainBoard:" << pThinkPadComputer->GetMainBoard() << endl;
cout << "Ram:" << pThinkPadComputer->GetRam() << endl;
cout << "VideoCard:" << pThinkPadComputer->GetVideoCard() << endl;
cout << "------Yoga------" << endl;
cout << "CPU:" << pYogaComputer->GetCPU() << endl;
cout << "MainBoard:" << pYogaComputer->GetMainBoard() << endl;
cout << "Ram:" << pYogaComputer->GetRam() << endl;
cout << "VideoCard:" << pYogaComputer->GetVideoCard() << endl;
SAFE_DELETE(pYogaComputer);
SAFE_DELETE(pThinkPadComputer);
SAFE_DELETE(pYogaBuilder);
SAFE_DELETE(pTPBuilder);
SAFE_DELETE(pDirector);
getchar();
return 0;
}
輸出:
—–ThinkPad—–
CPU : i5 - 6200U
Mainboard : Intel DH57DD
Ram : DDR4
VideoCard : NVIDIA Geforce 920MX
—–Yoga—–
CPU : i7 - 7500U
Mainboard : Intel DP55KG
Ram : DDR5
VideoCard : NVIDIA GeForce 940MX
如果需要建立更多的產品,只需要一個 ConcreteBuilder 即可,並且所有的程式碼都基本相同,客戶端還可以使用此模式輕鬆地建立複雜的產品。
五、優缺點
優點:
1、建造者獨立,易擴充套件。
2、便於控制細節風險。
缺點:
1、產品必須有共同點,範圍有限制。
2、如內部變化複雜,會有很多的建造類。