feat: builder pattern
This commit is contained in:
parent
3928379d6f
commit
58a01eb680
@ -1,8 +1,101 @@
|
|||||||
#include <iostream>
|
#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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
std::cout << "Builder" << std::endl;
|
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;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user