diff --git a/cpp/patterns/CMakeLists.txt b/cpp/patterns/CMakeLists.txt index d2f4bde..7f365d2 100644 --- a/cpp/patterns/CMakeLists.txt +++ b/cpp/patterns/CMakeLists.txt @@ -19,4 +19,5 @@ add_subdirectory(singleton) add_subdirectory(adapter) add_subdirectory(bridge) add_subdirectory(factory) +add_subdirectory(prototype) add_subdirectory(abstract-factory) diff --git a/cpp/patterns/prototype/CMakeLists.txt b/cpp/patterns/prototype/CMakeLists.txt new file mode 100644 index 0000000..d779585 --- /dev/null +++ b/cpp/patterns/prototype/CMakeLists.txt @@ -0,0 +1,20 @@ +############################################################################### +## Author: Shaun Reed ## +## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ## +## About: A project for practicing the prototype C++ design pattern ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +# +cmake_minimum_required(VERSION 3.15) +project( + #[[NAME]] Prototype + VERSION 1.0 + DESCRIPTION "An example of the prototype design pattern in C++" + LANGUAGES CXX +) +add_compile_options("-Wall") + +add_library(prototype "prototype.cpp") +add_executable(prototype-test "main.cpp") +target_link_libraries(prototype-test prototype) diff --git a/cpp/patterns/prototype/main.cpp b/cpp/patterns/prototype/main.cpp new file mode 100644 index 0000000..57439b9 --- /dev/null +++ b/cpp/patterns/prototype/main.cpp @@ -0,0 +1,21 @@ + +#include + +#include "prototype.hpp" + +int main(const int argc, const char * argv[]) { + // Create a new prototype factory + auto *factory = new PrototypeFactory; + + // Create a gear by cloning from factory prototypes + auto *gear = factory->createPrototype(Types::GEAR); + gear->show(); + + // Create a spring by cloning from factory prototypes + auto *spring = factory->createPrototype(Types::SPRING); + spring->show(); + + // Create a spring by cloning from an existing spring + auto *otherSpring = spring->clone(); + otherSpring->show(); +} diff --git a/cpp/patterns/prototype/prototype.cpp b/cpp/patterns/prototype/prototype.cpp new file mode 100644 index 0000000..f37fe0c --- /dev/null +++ b/cpp/patterns/prototype/prototype.cpp @@ -0,0 +1,8 @@ + +#include "prototype.hpp" + +PrototypeFactory::PrototypeFactory() +{ + prototypes[Types::GEAR] = new Gear(1.5f); + prototypes[Types::SPRING] = new Spring(2.25f); +} diff --git a/cpp/patterns/prototype/prototype.hpp b/cpp/patterns/prototype/prototype.hpp new file mode 100644 index 0000000..140bbdc --- /dev/null +++ b/cpp/patterns/prototype/prototype.hpp @@ -0,0 +1,58 @@ + +#ifndef PROTOTYPE_HPP +#define PROTOTYPE_HPP + +#include +#include +#include +#include + +#include "prototype.hpp" + +enum Types { + GEAR = 0, + SPRING, +}; + +class Prototype { +public: + Prototype(std::string name_, float price_) : + name(std::move(name_)), price(price_) {} + virtual ~Prototype() = default; + + virtual Prototype *clone() const = 0; + virtual void setField(std::string field_) { field = std::move(field_);} + + void show() const { std::cout << name << " with price: " << price << std::endl;} + +protected: + std::string name; + float price; + std::string field; +}; + +class Gear : public Prototype { +public: + explicit Gear(const float &price_) : Prototype("Gear", price_) {} + + Prototype *clone() const override { return new Gear(*this);} +}; + +class Spring : public Prototype { +public: + explicit Spring(const float &price_) : Prototype("Spring", price_) {} + + Prototype *clone() const override { return new Spring(*this);} +}; + +class PrototypeFactory { +public: + PrototypeFactory(); + + Prototype *createPrototype(Types type) { return prototypes[type]->clone();} + +private: + std::unordered_map prototypes; +}; + +#endif // PROTOTYPE_HPP