一、概述
1、建造者模式:將一個復雜對象的構建和它的表示分離,使得同樣的構建過程可以創建不同的表示
2、將客戶端與包含多個部件的復雜對象的創建過程分離,客戶端無須知道復雜對象的內部組成部分與裝配方式,只需要知道所需建造者的類型即可
3、關注如何逐步創建一個復雜的對象,不同的建造者定義了不同的創建過程
4、總的來說,建造者模式適合用于構建復雜對象,或者構建過程種對象需要一定的組裝順序或邏輯的情景,能夠提供更好的靈活性和可維護性
二、建造者模式的結構
建造者模式包含以下4個角色
(1)Builder(抽象建造者)
(2)ConcreteBuilder(具體建造者)
(3)Product(產品)
(4)Director(指揮者)
三、模式優點
1、客戶端不必知道產品內部組成的細節,將產品本身與產品的創建過程解耦,使得相同的創建過程可以創建不同的產品對象
2、每一個具體建造者都相對對立,與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者,擴展方便,符合開閉原則
3、可以更加精細地控制產品地創建過程
四、模式缺點
1、建造者模式所創建的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,不適合使用建造者模式,因此其使用范圍受到一定的限制
2、如果產品的內部變化復雜,可能會需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大,增加了系統的理解難度和運行成本
五、模式適用環境
1、需要生成的產品對象有復雜的內部結構,這些產品對象通常包含多個成員變量
2、需要生成的產品對象的屬性相互依賴,需要指定其生成順序
3、對象的創建過程獨立于該對象的類。在建造者模式種通過引入了指揮者類,將創建過程封裝在指揮者類種,而不在建造者類和客戶類中
4、隔離復雜對象的創建和使用,并使得相同的創建過程可以創建不同的產品
六、示例代碼
#include <iostream>
using namespace std;//產品類
class Computer
{
public:void setCPU(const string& cpu){m_cpu = cpu;}void setRAM(int ram){m_ram = ram;}void setStorage(const string& storage){m_storage = storage;}void showInfo(){cout << "Computer Configuration:" << endl;cout << "- CPU:" << m_cpu << endl;cout << "- RAM:" << m_ram << endl;cout << "- Storage:" << m_storage << endl;}
private:string m_cpu;int m_ram;string m_storage;
};//抽象建造者類:ComputerBuilder
class ComputerBuilder
{
public:virtual void buildCPU() const = 0;virtual void buildRAM() const = 0;virtual void buildStorage() const = 0;virtual Computer* getResult() const = 0;
};//具體建造者類:ConcreteComputerBuilder
class ConcreteComputerBuilder : public ComputerBuilder
{
public:ConcreteComputerBuilder(): m_computer(new Computer){}void buildCPU() const override{m_computer->setCPU("Intel i7");}void buildRAM() const override{m_computer->setRAM(16);}void buildStorage() const override{m_computer->setStorage("512GB SSD");}Computer* getResult() const override{return m_computer;}private:Computer* m_computer;
};//指揮者類:Director
class Director
{
public:Computer* createComputer(ComputerBuilder* builder){builder->buildCPU();builder->buildRAM();builder->buildStorage();return builder->getResult();}
};int main()
{Director director;ConcreteComputerBuilder builder;Computer* computer = director.createComputer(&builder);computer->showInfo();delete computer;return 0;
}