feat: builder pattern
This commit is contained in:
parent
3928379d6f
commit
58a01eb680
@ -1,8 +1,101 @@
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
|
||||
std::string join(const std::vector<std::string> &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<std::string> 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<Product>(builder.getProduct());
|
||||
simple_product->listParts();
|
||||
|
||||
builder.reset();
|
||||
director.buildFullProduct();
|
||||
auto full_product = std::unique_ptr<Product>(builder.getProduct());
|
||||
full_product->listParts();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
Reference in New Issue
Block a user