diff --git a/cpp/patterns/factory/CMakeLists.txt b/cpp/patterns/factory/CMakeLists.txt new file mode 100644 index 0000000..4a1719a --- /dev/null +++ b/cpp/patterns/factory/CMakeLists.txt @@ -0,0 +1,21 @@ +############################################################################### +## Author: Shaun Reed ## +## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ## +## About: A project for practicing the factory C++ design pattern ## +## ## +## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ## +############################################################################## +# +cmake_minimum_required(VERSION 3.15) +project( + #[[NAME]] Factory + VERSION 1.0 + DESCRIPTION "An example of the factory design pattern in C++" + LANGUAGES CXX +) +add_compile_options("-Wall") + +add_library(parts "parts.cpp") +add_library(factory "factory.cpp") +add_executable(factory-test "main.cpp") +target_link_libraries(factory-test factory parts) diff --git a/cpp/patterns/factory/factory.cpp b/cpp/patterns/factory/factory.cpp new file mode 100644 index 0000000..d310c5d --- /dev/null +++ b/cpp/patterns/factory/factory.cpp @@ -0,0 +1,42 @@ + +#include + +#include "factory.hpp" + +Part* GearFactory::requestPart() { + // Create a new part + Part * newPart = makePart(); + // Increment the QTY for part in AbstractFactory::inventory base class + // + If the item is not in the inventory map, this will also add it first. + inventory[newPart->getName()]++; + // Make the requested part + return newPart; +} + +Part* GearFactory::requestPart(std::string partName, float price) +{ + Part * newPart = makePart(partName, price); + inventory[newPart->getName()]++; + return newPart; +} + +void GearFactory::showStock() const +{ + for (const auto &item : inventory) { + if (item.first.empty()) continue; // Don't show an empty item + std::cout << item.first << " QTY in stock: " << item.second << std::endl; + } +} + + +/*****************************************************************************/ +// Gear + +Part* GearFactory::makePart() { + return new Gear(); +} + +Part* GearFactory::makePart(std::string name, float price) +{ + return new Gear(name, price); +} diff --git a/cpp/patterns/factory/factory.hpp b/cpp/patterns/factory/factory.hpp new file mode 100644 index 0000000..7d643fe --- /dev/null +++ b/cpp/patterns/factory/factory.hpp @@ -0,0 +1,33 @@ + +#ifndef FACTORY_HPP +#define FACTORY_HPP + +#include +#include +#include +#include +#include + +#include "parts.hpp" + +// Gear Concrete Factory +class GearFactory { +public: + explicit GearFactory(std::string name_="GearFactory") : + name(std::move(name_)) {} + + Part* requestPart(); + Part* requestPart(std::string partName, float price); + void showStock() const; + std::string getName() const { return name;} + +protected: + Part* makePart(); + Part* makePart(std::string name, float price); + +private: + std::string name; + std::unordered_map inventory; +}; + +#endif // FACTORY_HPP diff --git a/cpp/patterns/factory/main.cpp b/cpp/patterns/factory/main.cpp new file mode 100644 index 0000000..39a04c4 --- /dev/null +++ b/cpp/patterns/factory/main.cpp @@ -0,0 +1,24 @@ + +#include +#include +#include +#include + +#include "factory.hpp" + +int main(const int argc, const char * argv[]) { + // Testing GearFactory + GearFactory gearFactory; + const int gearsRequired = 5; + + std::cout << "Testing " << gearFactory.getName() <<"...\nMaking 5 Gears...\n"; + for (int i = 0; i < gearsRequired; i++) gearFactory.requestPart(); + std::cout << std::endl << gearFactory.getName() << " inventory:\n"; + gearFactory.showStock(); + + // Making custom gears + for (int i = 0; i < gearsRequired; i++) gearFactory.requestPart("Big Gear", 2.5f); + std::cout << std::endl << gearFactory.getName() << " inventory:\n"; + gearFactory.showStock(); + +} diff --git a/cpp/patterns/factory/parts.cpp b/cpp/patterns/factory/parts.cpp new file mode 100644 index 0000000..00a0707 --- /dev/null +++ b/cpp/patterns/factory/parts.cpp @@ -0,0 +1,10 @@ + +#include "parts.hpp" + +/*****************************************************************************/ +// Gear + +Gear::Gear(std::string name, float price) { + partName = name; + partPrice = price; +} diff --git a/cpp/patterns/factory/parts.hpp b/cpp/patterns/factory/parts.hpp new file mode 100644 index 0000000..179e856 --- /dev/null +++ b/cpp/patterns/factory/parts.hpp @@ -0,0 +1,26 @@ + +#ifndef PARTS_HPP +#define PARTS_HPP + +#include + +class Part { +public: + std::string getName() const { return partName;} + float getPrice() const { return partPrice;} + +protected: + std::string partName; // The name of the part + float partPrice; // The partPrice of the part +}; + + +/*****************************************************************************/ +// Gear + +class Gear : public Part { +public: + explicit Gear(std::string name="Gear", float price = 1.0f); +}; + +#endif // PARTS_HPP