diff --git a/prototype/Prototype.cpp b/prototype/Prototype.cpp new file mode 100644 index 0000000..4e48ebb --- /dev/null +++ b/prototype/Prototype.cpp @@ -0,0 +1,84 @@ +/* + * C++ Design Patterns: Prototype + * Author: Jakub Vojvoda [github.com/JakubVojvoda] + * 2016 + * + * Source code is licensed under MIT licence + * (for more details see LICENCE) + * + */ + +#include + +/* + * Prototype + * declares an interface for cloning itself + */ +class Prototype { +public: + virtual Prototype *clone() = 0; + virtual std::string type() = 0; + // ... +}; + +/* + * Concrete Prototype A and B + * implement an operation for cloning itself + */ +class ConcretePrototypeA : public Prototype { +public: + Prototype *clone() { + return new ConcretePrototypeA; + } + std::string type() { + return "type A"; + } + // ... +}; + +class ConcretePrototypeB : public Prototype { +public: + Prototype *clone() { + return new ConcretePrototypeB; + } + std::string type() { + return "type B"; + } + // ... +}; + +/* + * Client + * creates a new object by asking a prototype to clone itself + */ +class Client { +public: + static Prototype* make(int index) { + return types[index]->clone(); + } + // ... + +private: + static Prototype* types[2]; +}; + +Prototype* Client::types[] = +{ + new ConcretePrototypeA, + new ConcretePrototypeB + // ... +}; + + +int main() +{ + Prototype* prototype; + + prototype = Client::make(0); + std::cout << "Prototype: " << prototype->type() << std::endl; + + prototype = Client::make(1); + std::cout << "Prototype: " << prototype->type() << std::endl; + + return 0; +} diff --git a/prototype/README.md b/prototype/README.md new file mode 100644 index 0000000..05d2dbc --- /dev/null +++ b/prototype/README.md @@ -0,0 +1,12 @@ +## Prototype + +Specify the kinds of objects to create using a prototypical instance, and create +new objects by copying this prototype. Pattern has creational purpose and deals +with object relationships, which are more dynamic. The pattern hides the complexities +of making new instances from the client. + +### When to use + +* when the classes to instantiate are specified at run-time +* to avoid building a class hierarchy of factories that parallels the class hierarchy of products +* when instances of a class can have one of only a few different combinations of state