#include #include #include #include std::string join(const std::vector &values, const std::string &separator) { if (values.empty()) { return ""; } else { return std::accumulate( std::next(values.begin()), values.end(), values.front(), [&separator](const std::string &left, const std::string &right) { return left + separator + right; } ); } } class Product { public: std::vector parts; void listParts() const { std::cout << "Parts: " << join(parts, ", ") << std::endl; } }; class Builder { public: virtual ~Builder() = default; virtual const Builder &addPartA() const = 0; virtual const Builder &addPartB() const = 0; virtual const Builder &addPartC() const = 0; }; class ConcreteBuilder : public Builder { private: Product *product = nullptr; public: ConcreteBuilder() { reset(); } ~ConcreteBuilder() { delete product; } void reset() { if (product != nullptr) { delete product; } product = new Product(); } const Builder &addPartA() const override { product->parts.push_back("Part A"); return *this; } const Builder &addPartB() const override { product->parts.push_back("Part B"); return *this; } const Builder &addPartC() const override { product->parts.push_back("Part C"); return *this; } Product *getProduct() { Product *result = product; product = nullptr; return result; } }; class Director { private: Builder *builder = nullptr; public: Director(Builder *builder) : builder(builder) {} void buildSimpleProduct() { builder->addPartA(); } void buildFullProduct() { builder->addPartA().addPartB().addPartC(); } }; int main(int argc, char *argv[]) { std::cout << "Builder" << std::endl; ConcreteBuilder builder = ConcreteBuilder(); Director director(&builder); director.buildSimpleProduct(); auto simple_product = std::unique_ptr(builder.getProduct()); simple_product->listParts(); builder.reset(); director.buildFullProduct(); auto full_product = std::unique_ptr(builder.getProduct()); full_product->listParts(); return EXIT_SUCCESS; }