Add abstract-factory pattern example
This commit is contained in:
parent
54426cbe5b
commit
baabfa439a
|
@ -0,0 +1,21 @@
|
|||
###############################################################################
|
||||
## Author: Shaun Reed ##
|
||||
## Legal: All Content (c) 2021 Shaun Reed, all rights reserved ##
|
||||
## About: A project for practicing the abstract factory C++ design pattern ##
|
||||
## ##
|
||||
## Contact: shaunrd0@gmail.com | URL: www.shaunreed.com | GitHub: shaunrd0 ##
|
||||
##############################################################################
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(
|
||||
#[[NAME]] AbstractFactory
|
||||
VERSION 1.0
|
||||
DESCRIPTION "An example of the abstract factory design pattern in C++"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
add_compile_options("-Wall")
|
||||
|
||||
add_library(parts "parts.cpp")
|
||||
add_library(abstract-factory "factory.cpp")
|
||||
add_executable(abstract-factory-test "main.cpp")
|
||||
target_link_libraries(abstract-factory-test abstract-factory parts)
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
#ifndef FACTORY_HPP
|
||||
#define FACTORY_HPP
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "parts.hpp"
|
||||
|
||||
class AbstractFactory {
|
||||
public:
|
||||
AbstractFactory(std::string name_): name(std::move(name_)) {}
|
||||
virtual ~AbstractFactory() = default;
|
||||
|
||||
Part* requestPart();
|
||||
Part* requestPart(std::string partName, float price);
|
||||
void showStock() const;
|
||||
std::string getName() const { return name;}
|
||||
|
||||
protected:
|
||||
virtual Part* makePart() = 0;
|
||||
virtual Part* makePart(std::string name, float price) = 0;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
std::unordered_map<std::string, int> inventory;
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
// Gear Concrete Factory
|
||||
|
||||
class GearFactory : public AbstractFactory {
|
||||
public:
|
||||
explicit GearFactory(std::string name_="GearFactory") :
|
||||
AbstractFactory(std::move(name_)) {}
|
||||
|
||||
protected:
|
||||
Part* makePart() override;
|
||||
Part* makePart(std::string name, float price);
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
// Spring Concrete Factory
|
||||
|
||||
class SpringFactory : public AbstractFactory {
|
||||
public:
|
||||
explicit SpringFactory (std::string name_="SpringFactory"):
|
||||
AbstractFactory(std::move(name_)) {}
|
||||
|
||||
protected:
|
||||
Part* makePart() override;
|
||||
Part* makePart(std::string name, float price);
|
||||
};
|
||||
|
||||
#endif // FACTORY_HPP
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include "abstract-factory.hpp"
|
||||
|
||||
Part* AbstractFactory::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* AbstractFactory::requestPart(std::string partName, float price)
|
||||
{
|
||||
Part * newPart = makePart(partName, price);
|
||||
inventory[newPart->getName()]++;
|
||||
return newPart;
|
||||
}
|
||||
|
||||
void AbstractFactory::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);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
// Spring
|
||||
|
||||
Part* SpringFactory::makePart() {
|
||||
return new Spring();
|
||||
}
|
||||
|
||||
Part *SpringFactory::makePart(std::string name, float price)
|
||||
{
|
||||
return new Spring(name, price);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
#include <array>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "abstract-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();
|
||||
|
||||
// Testing SpringFactory
|
||||
SpringFactory springFactory;
|
||||
const int springsRequired = 5;
|
||||
for (int i = 0; i < springsRequired; i++) springFactory.requestPart();
|
||||
std::cout << std::endl << springFactory.getName() << " inventory:\n";
|
||||
springFactory.showStock();
|
||||
|
||||
|
||||
// Making custom gears and springs
|
||||
for (int i = 0; i < gearsRequired; i++) gearFactory.requestPart("Big Gear", 2.5f);
|
||||
std::cout << std::endl << gearFactory.getName() << " inventory:\n";
|
||||
gearFactory.showStock();
|
||||
|
||||
for (int i = 0; i < springsRequired; i++) springFactory.requestPart("Big Spring", 5.0f);
|
||||
std::cout << std::endl << springFactory.getName() << " inventory:\n";
|
||||
springFactory.showStock();
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#include "parts.hpp"
|
||||
|
||||
/*****************************************************************************/
|
||||
// Gear
|
||||
|
||||
Gear::Gear(std::string name, float price) {
|
||||
partName = name;
|
||||
partPrice = price;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
// Spring
|
||||
|
||||
Spring::Spring(std::string name, float price) {
|
||||
partName = name;
|
||||
partPrice = price;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
#ifndef PARTS_HPP
|
||||
#define PARTS_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
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:
|
||||
Gear(std::string name="Gear", float price = 1.0f);
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
// Spring
|
||||
|
||||
class Spring : public Part {
|
||||
public:
|
||||
Spring(std::string name = "Spring", float price = 2.0f);
|
||||
};
|
||||
|
||||
#endif // PARTS_HPP
|
Loading…
Reference in New Issue