赞
踩
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示的意图
用了建造者模式,那么用户就只需要指定需要构建的类型就可以得到它们,而具体构造的细节和过程不需要知道
概括地说,Builder是为创建一个Product对象的各个部件指定的抽象接口
而ConcreteBuilder是具体的建造者,实现Builder接口,构造和装配各个部件,Product是具体的产品
Director是指挥者,是构建一个使用Builder接口的对象。
什么时候需要用到建造者模式?
当我们需要创建一些复杂的对象,这些对象内部构建间的顺序通常是稳定的,但是对象内部的构建通常面临着复杂的变化
实现方法
基本代码如下
#include <iostream> #include <vector> #include <string> using std::cout; // 当产品非常复杂并且需要大量配置的时候,使用生成器模式非常有意义 // 各种构造器的结果可能并不总是遵循相同的接口 class Product1 { public: std::vector<std::string> parts_; void ListParts() const { cout << "Product parts: "; for (size_t i = 0; i < parts_.size(); i++) { if (parts_[i] == parts_.back()) { cout << parts_[i]; } else { cout << parts_[i] << ", "; } } cout << "\n\n"; } }; // Builder 接口指定了创建 Product 对象不同部分的方法。 class Builder { public: virtual ~Builder(){}; virtual void ProducePartA() const = 0; virtual void ProducePartB() const = 0; virtual void ProducePartC() const = 0; }; // ConcreteBuilder 类遵循Builder类提供的接口,并提供建造步骤的具体实现。因此ConcreteBuilder应该有许多个,实现方法可以不同 class ConcreteBuilder1 : public Builder { private: // 一个新的构建器实例应该包含一个空白的产品对象,用于进一步的组装。 Product1 *product; public: ConcreteBuilder1() { this->Reset(); } ~ConcreteBuilder1() { delete product; } void Reset() { this->product = new Product1(); } // 所有生产步骤均使用同一产品实例 void ProducePartA() const override { this->product->parts_.push_back("PartA1"); } void ProducePartB() const override { this->product->parts_.push_back("PartB1"); } void ProducePartC() const override { this->product->parts_.push_back("PartC1"); } // 具体构建器应该提供自己的方法来检索结果。 // 这是因为不同类型的构建器可能会创建完全不同的产品,这些产品不遵循相同的接口。 // 因此,此类方法不能在基本构建器接口中声明(至少在静态类型编程语言中不能) // 通常,在将最终结果返回给客户端后,构建器实例应该准备好开始生产另一个产品。 // 这就是为什么在 `getProduct` 方法主体末尾调用 reset 方法是一种常见做法。 // 但是,这种行为不是强制性的,您可以让构建器等待来自客户端代码的明确 reset 调用,然后再处理之前的结果。 // 一旦调用 GetProduct,此函数的用户就有责任释放此内存。使用智能指针来避免内存泄漏可能是一个更好的选择 Product1 *GetProduct() { Product1 *result = this->product; this->Reset(); return result; } }; // Director 负责按照特定的顺序执行构建顺序, class Director { private: Builder *builder; // Director 可与客户端代码传递给它的任何构建器实例配合使用。这样,客户端代码可能会改变新组装产品的最终类型。 public: void set_builder(Builder *builder) { this->builder = builder; } // Director 可以使用相同的构建步骤构建多个产品变体 void BuildMinimalViableProduct() { this->builder->ProducePartA(); } void BuildFullFeaturedProduct() { this->builder->ProducePartA(); this->builder->ProducePartB(); this->builder->ProducePartC(); } }; // 客户端代码创建一个构建器对象,将其传递给Director,然后启动构造过程。最终结果从构建器对象中检索。 void ClientCode(Director &director) { ConcreteBuilder1 *builder = new ConcreteBuilder1(); director.set_builder(builder); cout << "Standard basic product:\n"; director.BuildMinimalViableProduct(); Product1 *p = builder->GetProduct(); p->ListParts(); delete p; cout << "Standard full featured product:\n"; director.BuildFullFeaturedProduct(); p = builder->GetProduct(); p->ListParts(); delete p; // 也可以不使用Director类直接使用构造模式 cout << "Custom product:\n"; builder->ProducePartA(); builder->ProducePartC(); p = builder->GetProduct(); p->ListParts(); delete p; delete builder; } int main() { Director *director = new Director(); ClientCode(*director); delete director; return 0; }
输出
Standard basic product:
Product parts: PartA1
Standard full featured product:
Product parts: PartA1, PartB1, PartC1
Custom product:
Product parts: PartA1, PartC1
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。