一、建造者模式說明
????????建造者模式(Builder Pattern)是一種創建型設計模式,它的主要目的是將一個復雜對象的構建過程與其表示分離,使得同樣的構建過程可以創建不同的表示。
在建造者模式中,通常涉及以下幾個角色:
產品(Product):
- 產品是要構建的復雜對象,包含多個部件。
- 產品通常是由多個部件組成的復雜對象,建造者模式的目標就是創建這個復雜對象。
抽象建造者(Builder):
- 抽象建造者定義了創建產品各個部件的抽象接口。
- 抽象建造者中通常包含多個方法,用于構建產品的各個部件,例如構建引擎、構建輪胎、構建座椅等。
- 它可以是一個抽象類或接口。
具體建造者(Concrete Builder):
- 具體建造者實現了抽象建造者接口,負責具體構建產品的各個部件。
- 每個具體建造者類對應一個特定的產品類型,并定義了具體構建該產品的過程。
- 具體建造者類通常包含私有成員變量用于保存構建過程中的臨時狀態,并提供方法來構建不同部件。
指揮者(Director):
- 指揮者負責調用具體建造者的方法來構建產品。
- 指揮者知道構建產品的具體步驟和順序,但不知道產品的具體細節。
- 指揮者根據客戶端的需求調用具體建造者的方法,將產品的構建過程與表示分離。
二、建造者模式樣例
#include <iostream>
#include <string>// 產品類
class Product {
public:void setPartA(const std::string& partA) {partA_ = partA;}void setPartB(const std::string& partB) {partB_ = partB;}void setPartC(const std::string& partC) {partC_ = partC;}void show() const {std::cout << "Product parts: " << partA_ << ", " << partB_ << ", " << partC_ << std::endl;}private:std::string partA_;std::string partB_;std::string partC_;
};// 抽象建造者類
class Builder {
public:virtual ~Builder() {}virtual void buildPartA() = 0;virtual void buildPartB() = 0;virtual void buildPartC() = 0;virtual Product getResult() = 0;
};// 具體建造者類A
class ConcreteBuilderA : public Builder {
public:void buildPartA() override {product_.setPartA("PartA by ConcreteBuilderA");}void buildPartB() override {product_.setPartB("PartB by ConcreteBuilderA");}void buildPartC() override {product_.setPartC("PartC by ConcreteBuilderA");}Product getResult() override {return product_;}private:Product product_;
};// 具體建造者類B
class ConcreteBuilderB : public Builder {
public:void buildPartA() override {product_.setPartA("PartA by ConcreteBuilderB");}void buildPartB() override {product_.setPartB("PartB by ConcreteBuilderB");}void buildPartC() override {product_.setPartC("PartC by ConcreteBuilderB");}Product getResult() override {return product_;}private:Product product_;
};// 指揮者類
class Director {
public:void construct(Builder& builder) {builder.buildPartA();builder.buildPartB();builder.buildPartC();}
};int main() {Director director;ConcreteBuilderA builderA;ConcreteBuilderB builderB;// 構建產品Astd::cout << "Product A:" << std::endl;director.construct(builderA);Product productA = builderA.getResult();productA.show();// 構建產品Bstd::cout << "\nProduct B:" << std::endl;director.construct(builderB);Product productB = builderB.getResult();productB.show();return 0;
}
三、建造者模式的場景
以下是一些適用建造者模式的具體場景:
????????游戲角色創建器:在游戲中,玩家可以選擇不同的角色并自定義其外觀、能力和裝備。建造者模式可以用于創建角色的建造器,每個具體建造者負責構建不同類型的角色,而指揮者負責組裝角色的各個部件,最終創建出完整的角色對象。
????????文檔生成器:在文檔生成器中,可能需要創建不同類型的文檔,例如簡歷、報告、新聞稿等。建造者模式可以用于創建文檔的建造器,每個具體建造者負責構建不同類型的文檔,而指揮者負責組裝文檔的各個部件,最終生成所需的文檔對象。
????????電腦組裝器:在電腦組裝器中,用戶可以選擇不同的硬件配置和外設,并自定義其性能和功能。建造者模式可以用于創建電腦的建造器,每個具體建造者負責構建不同配置的電腦,而指揮者負責組裝電腦的各個部件,最終組裝成用戶所需的電腦。
????????汽車定制器:在汽車定制器中,用戶可以選擇不同的汽車型號、顏色、配置和附件。建造者模式可以用于創建汽車的建造器,每個具體建造者負責構建不同配置的汽車,而指揮者負責組裝汽車的各個部件,最終定制成用戶所需的汽車。
????????食品套餐訂購系統:在食品套餐訂購系統中,用戶可以選擇不同的食品套餐、主食、配菜和飲料。建造者模式可以用于創建食品套餐的建造器,每個具體建造者負責構建不同套餐的各個部件,而指揮者負責組裝套餐的各個部件,最終生成用戶所需的套餐對象。
四、建造者模式優缺點
建造者模式具有以下優點和缺點:
優點:
????????分離構建過程和表示:建造者模式將一個復雜對象的構建過程與其表示分離,使得同樣的構建過程可以創建不同的表示,提高了系統的靈活性。
????????隱藏構建細節:建造者模式將對象的構建過程封裝起來,只向客戶端暴露一個簡單的構建接口,客戶端不需要關心對象的構建細節,降低了客戶端與具體構建過程的耦合度。
????????更加精細地控制構建過程:建造者模式可以讓客戶端按照需要靈活地指定構建順序和選擇構建部件,可以更加精細地控制對象的構建過程,滿足不同的需求。
????????增加對象的可復用性:由于建造者模式將對象的構建過程封裝起來,可以在不改變原有代碼的情況下,通過新增具體建造者類來創建新的對象表示,提高了對象的可復用性。
????????增加系統的擴展性:由于建造者模式將構建過程和表示分離,新增具體建造者類或修改指揮者類不會影響其他部分的代碼,增加了系統的擴展性。
缺點:
????????增加系統復雜度:建造者模式引入了多個角色和類,增加了系統的復雜度,可能會導致代碼量增加,不利于理解和維護。
????????不適用于對象較簡單的情況:當對象的構建過程比較簡單,或者對象的內部結構比較穩定時,使用建造者模式可能會顯得繁瑣,不適合使用。
????????不利于組裝順序的靈活性:建造者模式將構建過程固化在建造者類中,可能會限制對象組裝順序的靈活性,如果需要改變組裝順序,則需要修改建造者類或指揮者類。
????????可能會產生多余的對象:由于建造者模式將構建過程和表示分離,可能會導致在構建對象過程中產生多余的對象,增加了系統的資源消耗。