I have tried to implement the abstract factory design pattern. This is a complicated pattern. Can you review? My understanding of the pattern is: the objects to be constructed have two or more member object properties (here color and shape), each of which are created by a factory. The final objects themselves are also created by a factory, so we need a factory of factories. The objects and the member object properties are abstracted.
Compiling:
g++ -Wall -g -std=c++1y -Wall -c /mnt/home/Data_MaOt/Short_C_and_Cpp_progs/DesignPatterns/04_AbstractFactoryShapesColors/CBlue.cpp -o obj/Debug/CBlue.o
g++ -Wall -g -std=c++1y -Wall -c /mnt/home/Data_MaOt/Short_C_and_Cpp_progs/DesignPatterns/04_AbstractFactoryShapesColors/CCircle.cpp -o obj/Debug/CCircle.o
g++ -Wall -g -std=c++1y -Wall -c /mnt/home/Data_MaOt/Short_C_and_Cpp_progs/DesignPatterns/04_AbstractFactoryShapesColors/CColoredShape.cpp -o obj/Debug/CColoredShape.o
g++ -Wall -g -std=c++1y -Wall -c /mnt/home/Data_MaOt/Short_C_and_Cpp_progs/DesignPatterns/04_AbstractFactoryShapesColors/CColorFactory.cpp -o obj/Debug/CColorFactory.o
g++ -Wall -g -std=c++1y -Wall -c /mnt/home/Data_MaOt/Short_C_and_Cpp_progs/DesignPatterns/04_AbstractFactoryShapesColors/CFactoryOfFactories.cpp -o obj/Debug/CFactoryOfFactories.o
g++ -Wall -g -std=c++1y -Wall -c /mnt/home/Data_MaOt/Short_C_and_Cpp_progs/DesignPatterns/04_AbstractFactoryShapesColors/CGreen.cpp -o obj/Debug/CGreen.o
g++ -Wall -g -std=c++1y -Wall -c /mnt/home/Data_MaOt/Short_C_and_Cpp_progs/DesignPatterns/04_AbstractFactoryShapesColors/CRectangle.cpp -o obj/Debug/CRectangle.o
g++ -Wall -g -std=c++1y -Wall -c /mnt/home/Data_MaOt/Short_C_and_Cpp_progs/DesignPatterns/04_AbstractFactoryShapesColors/CRed.cpp -o obj/Debug/CRed.o
g++ -Wall -g -std=c++1y -Wall -c /mnt/home/Data_MaOt/Short_C_and_Cpp_progs/DesignPatterns/04_AbstractFactoryShapesColors/CShapeFactory.cpp -o obj/Debug/CShapeFactory.o
g++ -Wall -g -std=c++1y -Wall -c /mnt/home/Data_MaOt/Short_C_and_Cpp_progs/DesignPatterns/04_AbstractFactoryShapesColors/CTriangle.cpp -o obj/Debug/CTriangle.o
g++ -Wall -g -std=c++1y -Wall -c /mnt/home/Data_MaOt/Short_C_and_Cpp_progs/DesignPatterns/04_AbstractFactoryShapesColors/main.cpp -o obj/Debug/main.o
g++ -o bin/Debug/04_AbstractFactoryShapesColors obj/Debug/CBlue.o obj/Debug/CCircle.o obj/Debug/CColoredShape.o obj/Debug/CColorFactory.o obj/Debug/CFactoryOfFactories.o obj/Debug/CGreen.o obj/Debug/CRectangle.o obj/Debug/CRed.o obj/Debug/CShapeFactory.o obj/Debug/CTriangle.o obj/Debug/main.o
Output file is bin/Debug/04_AbstractFactoryShapesColors with size 351,28 KB
Process terminated with status 0 (0 minute(s), 9 second(s))
0 error(s), 0 warning(s) (0 minute(s), 9 second(s))
Output
int main(): Started.
void CColoredShape::Identify() const: I am a red circle.
void CColoredShape::Identify() const: I am a blue triangle.
void CColoredShape::Identify() const: I am a green rectangle.
int main(): Done.
CColorBase.h
#ifndef CCOLORBASE_H
#define CCOLORBASE_H
#include <string.h>
class CColorBase
{
public:
virtual const std::string GetColor() const noexcept = 0;
};
#endif // CCOLORBASE_H
CFactoryBase.h
#ifndef CFACTORYBASE_H
#define CFACTORYBASE_H
#include <memory>
#include "string"
#include "CColorBase.h"
#include "CShapeBase.h"
class CFactoryBase
{
public:
virtual std::unique_ptr<CColorBase> GetColor(const std::string aColor) const noexcept = 0;
virtual std::unique_ptr<CShapeBase> GetShape(const std::string aShape) const noexcept = 0;
};
#endif // CFACTORYBASE_H
CShapeBase.h
#ifndef CSHAPEBASE_H
#define CSHAPEBASE_H
#include "string"
class CShapeBase
{
public:
virtual const std::string GetShape() const noexcept = 0;
};
#endif // CSHAPEBASE_H
CBlue.cpp
#include <iostream>
#include "CBlue.h"
const std::string CBlue::GetColor() const noexcept
{
return std::string("blue");
}
CBlue.h
#include "CColorBase.h"
class CBlue : public CColorBase
{
public:
const std::string GetColor() const noexcept override;
};
CCircle.cpp
#include <iostream>
#include "CCircle.h"
const std::string CCircle::GetShape() const noexcept
{
return std::string("circle");
}
CCircle.h
#ifndef CCIRCLE_H
#define CCIRCLE_H
#include "CShapeBase.h"
class CCircle : public CShapeBase
{
public:
const std::string GetShape() const noexcept override;
};
#endif // CCIRCLE_H
CColorFactory.cpp
#include <iostream>
#include "CColorFactory.h"
#include "CRed.h"
#include "CGreen.h"
#include "CBlue.h"
std::unique_ptr<CShapeBase> CColorFactory::GetShape(std::string aShapeString) const noexcept
{
std::cout << __PRETTY_FUNCTION__ << ": You should not call this method." << std::endl;
exit(-1);
}
std::unique_ptr<CColorBase> CColorFactory::GetColor(std::string aColorString) const noexcept
{
std::unique_ptr<CColorBase> myColorBase = nullptr;
if (aColorString.compare("Red") == 0)
{
myColorBase.reset(new CRed());
}
else if (aColorString.compare("Blue") == 0)
{
myColorBase.reset(new CBlue());
}
else if (aColorString.compare("Green") == 0)
{
myColorBase.reset(new CGreen());
}
else
{
std::cout << __PRETTY_FUNCTION__ << ": Unknown color " << aColorString << std::endl;
exit(-1);
}
return myColorBase;
}
CColorFactory.h
#ifndef CCOLORFACTORY_H
#define CCOLORFACTORY_H
#include <memory>
#include "CFactoryBase.h"
class CColorFactory : public CFactoryBase
{
public:
std::unique_ptr<CShapeBase> GetShape(const std::string aShapeString) const noexcept override;
std::unique_ptr<CColorBase> GetColor(const std::string aColorString) const noexcept override;
};
#endif // CCOLORFACTORY_H
CColoredShape.cpp
#include <iostream>
#include "CColoredShape.h"
#include "CFactoryBase.h"
#include "CFactoryOfFactories.h"
CColoredShape::CColoredShape(const std::string& aShape, const std::string& aColor) noexcept
{
std::unique_ptr<CFactoryBase> shapeFactory = nullptr;
std::unique_ptr<CFactoryBase> colorFactory = nullptr;
std::unique_ptr<CShapeBase> shape = nullptr;
std::unique_ptr<CColorBase> color = nullptr;
shapeFactory = CFactoryOfFactories::GetFactory("Shape");
colorFactory = CFactoryOfFactories::GetFactory("Color");
iShape = shapeFactory->GetShape(aShape);
iColor = colorFactory->GetColor(aColor);
}
void CColoredShape::Identify() const noexcept
{
std::cout << __PRETTY_FUNCTION__ << ": I am a " << iColor->GetColor() << " " << iShape->GetShape() << "." << std::endl;
}
CColoredShape.h
#ifndef CCOLOREDSHAPE_H
#define CCOLOREDSHAPE_H
#include <string>
#include <memory>
#include "CColorBase.h"
#include "CShapeBase.h"
class CColoredShape
{
public:
CColoredShape(const std::string& aShape, const std::string& aColor) noexcept;
void Identify() const noexcept;
private:
std::unique_ptr<CColorBase> iColor;
std::unique_ptr<CShapeBase> iShape;
};
#endif // CCOLOREDSHAPE_H
CFactoryOfFactories.cpp
#include <iostream>
#include "CFactoryOfFactories.h"
#include "CShapeFactory.h"
#include "CColorFactory.h"
std::unique_ptr<CFactoryBase> CFactoryOfFactories::GetFactory(std::string aFactoryString)
{
std::unique_ptr<CFactoryBase> myFactoryBase = nullptr;
if (aFactoryString.compare("Shape") == 0)
{
myFactoryBase.reset(new CShapeFactory());
}
else if (aFactoryString.compare("Color") == 0)
{
myFactoryBase.reset(new CColorFactory());
}
else
{
std::cout << __PRETTY_FUNCTION__ << ": Unkown factory " << aFactoryString << std::endl;
exit(-1);
}
return myFactoryBase;
}
CFactoryOfFactories.h
#ifndef CFACTORYOFFACTORIES_H
#define CFACTORYOFFACTORIES_H
#include <memory>
#include "CFactoryBase.h"
class CFactoryOfFactories
{
public:
static std::unique_ptr<CFactoryBase> GetFactory(const std::string aFactoryString);
};
#endif // CFACTORYOFFACTORIES_H
CGreen.cpp
#include <iostream>
#include "CGreen.h"
const std::string CGreen::GetColor() const noexcept
{
return std::string("green");
}
CGreen.h
#include "CColorBase.h"
class CGreen : public CColorBase
{
public:
const std::string GetColor() const noexcept override;
};
CRectangle.cpp
#include <iostream>
#include "CRectangle.h"
const std::string CRectangle::GetShape() const noexcept
{
return std::string("rectangle");
}
CRectangle.h
#ifndef CRECTANGLE_H
#define CRECTANGLE_H
#include "CShapeBase.h"
class CRectangle : public CShapeBase
{
public:
const std::string GetShape() const noexcept override;
};
#endif // CRECTANGLE_H
CRed.cpp
#include <iostream>
#include "CRed.h"
const std::string CRed::GetColor() const noexcept
{
return std::string("red");
}
CRed.h
#include "CColorBase.h"
class CRed : public CColorBase
{
public:
const std::string GetColor() const noexcept override;
};
CShapeFactory.cpp
#include "iostream"
#include "CShapeFactory.h"
#include "CCircle.h"
#include "CTriangle.h"
#include "CRectangle.h"
std::unique_ptr<CShapeBase> CShapeFactory::GetShape(std::string aShapeString) const noexcept
{
std::unique_ptr<CShapeBase> shapePtr = nullptr;
if (aShapeString.compare("Circle") == 0)
{
shapePtr.reset(new CCircle());
}
else if (aShapeString.compare("Rectangle") == 0)
{
shapePtr.reset(new CRectangle());
}
else if (aShapeString.compare("Triangle") ==0)
{
shapePtr.reset(new CTriangle());
}
else
{
std::cout << __PRETTY_FUNCTION__ << ": Unknown shape " << aShapeString << std::endl;
exit(-1);
}
return shapePtr;
}
std::unique_ptr<CColorBase> CShapeFactory::GetColor(std::string aColorString) const noexcept
{
std::cout << __PRETTY_FUNCTION__ << ": You should not call this method." << std::endl;
exit(-1);
}
CShapeFactory.h
#ifndef CSHAPEFACTORY_H
#define CSHAPEFACTORY_H
#include <memory>
#include "CFactoryBase.h"
class CShapeFactory : public CFactoryBase
{
private:
std::unique_ptr<CShapeBase> GetShape(const std::string aShapeString) const noexcept override;
std::unique_ptr<CColorBase> GetColor(const std::string aColorString) const noexcept override;
};
#endif // CSHAPEFACTORY_H
CTriangle.cpp
#include <iostream>
#include "CTriangle.h"
const std::string CTriangle::GetShape() const noexcept
{
return std::string("triangle");
}
CTriangle.h
#ifndef CTRIANGLE_H
#define CTRIANGLE_H
#include "CShapeBase.h"
class CTriangle : public CShapeBase
{
public:
const std::string GetShape() const noexcept override;
};
#endif // CTRIANGLE_H
main.cpp
#include <iostream>
#include "CColoredShape.h"
// Abstract factory design pattern
// Based on https://www.tutorialspoint.com/design_pattern/abstract_factory_pattern.htm
int main()
{
std::cout << __PRETTY_FUNCTION__ << ": Started." << std::endl;
CColoredShape redCircle = CColoredShape("Circle", "Red");
CColoredShape blueTriangle = CColoredShape("Triangle", "Blue");
CColoredShape greenRectangle = CColoredShape("Rectangle", "Green");
redCircle.Identify();
blueTriangle.Identify();
greenRectangle.Identify();
std::cout << __PRETTY_FUNCTION__ << ": Done." << std::endl;
}