Add abstract-factory pattern example
This commit is contained in:
		
							parent
							
								
									54426cbe5b
								
							
						
					
					
						commit
						baabfa439a
					
				
							
								
								
									
										21
									
								
								cpp/patterns/abstract-factory/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								cpp/patterns/abstract-factory/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@ -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)
 | 
				
			||||||
							
								
								
									
										60
									
								
								cpp/patterns/abstract-factory/abstract-factory.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								cpp/patterns/abstract-factory/abstract-factory.hpp
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
				
			||||||
							
								
								
									
										55
									
								
								cpp/patterns/abstract-factory/factory.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								cpp/patterns/abstract-factory/factory.cpp
									
									
									
									
									
										Normal file
									
								
							@ -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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								cpp/patterns/abstract-factory/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								cpp/patterns/abstract-factory/main.cpp
									
									
									
									
									
										Normal file
									
								
							@ -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();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										19
									
								
								cpp/patterns/abstract-factory/parts.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								cpp/patterns/abstract-factory/parts.cpp
									
									
									
									
									
										Normal file
									
								
							@ -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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										35
									
								
								cpp/patterns/abstract-factory/parts.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								cpp/patterns/abstract-factory/parts.hpp
									
									
									
									
									
										Normal file
									
								
							@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user