I am trying to make all the creational design patterns and I'm having some trouble with the abstract factory method. I normally program in Python, however, I had heard C++ was good for really having to understand design patterns explicitly, which is proving to be right, err.
I'm basically following this guide on Tutorials Point.
My question is how would I change my current code to correctly implement the abstract factory method in C++ with a factory producer as I believe its something to do with my Factory Producer extra layer of abstraction that is causing my issues. I have included all my code.
I tried to make a simple diagram to explain better but it's not the most formal UML but is essentially what I would like to make. My main.cpp
file should illustrate better the functionality I'm trying to understand how to make.
P.s. I'm just trying to improve to apply for jobs so please let me know if you have any feedback on writing better SO questions, coding style, variable naming or even C++ conventions.
Main
main.cpp - Main implementation file
Tests creating an abstract factory, abstract sword and abstract warrior.
#include "factoryproducer.h"
using namespace std;
int main(int argc, char *argv[]) {
AbstractFactory* warriorFactory = FactoryProducer::createFactory("warriorfactory");
Warrior* tinyWarrior = warriorFactory->createWarrior("tinywarrior");
Warrior* normalWarrior = warriorFactory->createWarrior("normalwarrior");
Warrior* largeWarrior = warriorFactory->createWarrior("largewarrior");
Warrior* giantWarrior = warriorFactory->createWarrior("giantwarrior");
cout<<tinyWarrior->getName().toStdString()<<endl;
cout<<normalWarrior->getName().toStdString()<<endl;
cout<<largeWarrior->getName().toStdString()<<endl;
cout<<giantWarrior->getName().toStdString()<<endl;
AbstractFactory* SwordFactory = FactoryProducer::createFactory("swordfactory");
Sword* tinySword = swordFactory->createSword("tinysword");
Sword* normalSword = swordFactory->createSword("normalsword");
Sword* largeSword = swordFactory->createSword("largesword");
Sword* giantSword = swordFactory->createSword("giantsword");
cout<<tinySword->getName().toStdString()<<endl;
cout<<normalSword->getName().toStdString()<<endl;
cout<<largeSword->getName().toStdString()<<endl;
cout<<giantSword->getName().toStdString()<<endl;
return a.exec();
}
Abstract Factory Class
abstractfactory.h - Abstract Factory header file
#ifndef ABSTRACTFACTORY_H
#define ABSTRACTFACTORY_H
#include "warrior.h"
#include "sword.h"
#include <QString>
class AbstractFactory {
public:
// Public Methods
~AbstractFactory();
virtual Warrior* createWarrior(QString warriorType) = 0;
virtual Sword* createSword(QString swordType) = 0;
};
#endif // ABSTRACTFACTORY_H
abstractfactory.cpp Abstract Factory implementation file
#include "abstractfactory.h"
AbstractFactory::~AbstractFactory(){}
Factory Producer Class
factoryproducer.h - Factory Producer header file
#ifndef FACTORYPRODUCER_H
#define FACTORYPRODUCER_H
#include "abstractfactory.h"
#include "warriorfactory.h"
#include "swordfactory.h"
#include <QString>
class FactoryProducer {
public:
// Public Methods
static AbstractFactory* createFactory(QString factoryType);
};
#endif // FACTORYPRODUCER_H
factoryproducer.cpp - Factory Producer implementation file
#include "factoryproducer.h"
AbstractFactory* AbstractFactory::createFactory(QString factoryType) {
if (factoryType == nullptr) {
return nullptr;
}
if (QString::compare(factoryType, "WARRIORFACTORY", Qt::CaseInsensitive) == 0) {
return new WarriorFactory();
}
if (QString::compare(factoryType, "SWORDFACTORY", Qt::CaseInsensitive) == 0) {
return new SwordFactory();
}
return nullptr;
}
Abstract Warrior Class
warrior.h - Abstract Warrior header file
#ifndef WARRIOR_H
#define WARRIOR_H
#include "tinywarrior.h"
#include "normalwarrior.h"
#include "largewarrior.h"
#include "giantwarrior.h"
#include <QString>
class Warrior {
public:
// Public Methods
~Warrior();
virtual QString getPicture() = 0;
};
#endif // WARRIOR_H
warrior.cpp - Abstract Warrior implementation file
#include "warrior.h"
Warrior::~Warrior(){}
Abstract Sword Class
sword.h - Abstract Sword header file
#ifndef SWORD_H
#define SWORD_H
#include "tinysword.h"
#include "normalsword.h"
#include "largesword.h"
#include "giantsword.h"
#include <QString>
class Sword {
public:
// Public Methods
~Sword();
virtual QString getName() = 0;
virtual QString getPicture() = 0;
};
#endif // SWORD_H
sword.cpp - Abstract Sword implementation file
#include "sword.h"
Sword::~Sword(){}
Concrete TinySword Class
tinysword.h - Concrete Tiny Sword header file
#ifndef TINYSWORD_H
#define TINYSWORD_H
#include "sword.h"
class TinySword : public Sword {
public:
// Public Methods
TinySword();
~TinySword();
QString getName();
QString getPicture();
private:
// Private Member Variables
QString m_name;
QString m_picture;
};
#endif // TINYSWORD_H
tinysword.cpp - Concrete Tiny Sword implementation file
#include "tinysword.h"
TinySword::TinySword(){
m_name = "Tiny Sword";
m_picture = "";
}
TinySword::~TinySword(){}
QString TinySword::getName() {
return m_name;
}
QString TinySword::getPicture() {
return m_picture;
}
Concrete Normal Sword
normalsword.h - Concrete Normal Sword header file
#ifndef NORMALSWORD_H
#define NORMALSWORD_H
#include "sword.h"
class NormalSword : public Sword {
public:
// Public Methods
NormalSword();
~NormalSword();
QString getName();
QString getPicture();
private:
// Private Member Variables
QString m_name;
QString m_picture;
};
#endif // NORMALSWORD_H
normalsword.cpp - Concrete Normal Sword implementation file
#include "normalsword.h"
NormalSword::NormalSword() {
m_name = "Normal Sword";
m_picture = "";
}
NormalSword::~NormalSword(){}
QString NormalSword::getName() {
return m_name;
}
QString NormalSword::getPicture() {
return m_picture;
}
Concrete Large Sword Class
largesword.h - Concrete Large Sword header file
#ifndef LARGESWORD_H
#define LARGESWORD_H
#include "sword.h"
class LargeSword : public Sword {
public:
// Public Methods
LargeSword();
~LargeSword();
QString getName();
QString getPicture();
private:
// Private Member Variables
QString m_name;
QString m_picture;
};
#endif // LARGESWORD_H
largesword.cpp - Concrete Large Sword implementation file
#include "largesword.h"
LargeSword::LargeSword() {
m_name = "Large Sword";
m_picture = "";
}
LargeSword::~LargeSword(){}
QString LargeSword::getName() {
return m_name;
}
QString LargeSword::getPicture() {
return m_picture;
}
Concrete Giant Sword Class
giantsword.h - Concrete Giant Sword header file
#ifndef GIANTSWORD_H
#define GIANTSWORD_H
#include "sword.h"
class GiantSword : public Sword {
public:
// Public Methods
GiantSword();
~GiantSword();
QString getName();
QString getPicture();
private:
// Private Member Variables
QString m_name;
QString m_picture;
};
#endif // GIANTSWORD_H
giantsword.cpp - Concrete Giant Sword implementation file
#include "giantsword.h"
GiantSword::GiantSword() {
m_name = "Giant Sword";
m_picture = "";
}
GiantSword::~GiantSword(){}
QString GiantSword::getName() {
return m_name;
}
QString GiantSword::getPicture() {
return m_picture;
}
Concrete Tiny Warrior Class
tinywarrior.h - Concrete Tiny Warrior header file
#ifndef TINYWARRIOR_H
#define TINYWARRIOR_H
#include "warrior.h"
class TinyWarrior : public Warrior {
public:
// Methods
TinyWarrior();
~TinyWarrior();
QString getPicture();
private:
// Private Member Variables
QString m_name;
QString m_picture;
};
#endif // TINYWARRIOR_H
tinywarrior.cpp - Concrete Tiny Warrior implementation file
#include "tinywarrior.h"
TinyWarrior::TinyWarrior(){
m_name = "Tiny Warrior";
m_picture = ":/images/tiny-warrior.png";
}
TinyWarrior::~TinyWarrior(){}
QString TinyWarrior::getName() {
return m_name;
}
QString TinyWarrior::getPicture() {
return m_picture;
}
Concrete Normal Warrior Class
normalwarrior.h - Concrete Normal Warrior header file
#ifndef NORMALWARRIOR_H
#define NORMALWARRIOR_H
#include "warrior.h"
class NormalWarrior : public Warrior {
public:
// Public Methods
NormalWarrior();
~NormalWarrior();
QString getName();
QString getPicture();
private:
// Private Member Variables
QString m_name;
QString m_picture;
};
#endif // NORMALWARRIOR_H
normalwarrior.cpp Concrete Normal Warrior implementation
#include "normalwarrior.h"
NormalWarrior::NormalWarrior() {
m_name = "Normal Warrior";
m_picture = ":/images/normal-warrior.png";
}
NormalWarrior::~NormalWarrior(){}
QString NormalWarrior::getName() {
return m_name;
}
QString NormalWarrior::getPicture() {
return m_picture;
}
Concrete Large Warrior Class
largewarrior.h Concrete Large Warrior header file
#ifndef LARGEWARRIOR_H
#define LARGEWARRIOR_H
#include "warrior.h"
class LargeWarrior : public Warrior {
public:
// Methods
LargeWarrior();
~LargeWarrior();
QString getName();
QString getPicture();
private:
// Private Member Variables
QString m_name;
QString m_picture;
};
#endif // LARGEWARRIOR_H
largewarrior.cpp Concrete Large Warrior implementation file
#include "largewarrior.h"
LargeWarrior::LargeWarrior(){
m_name = "Large Warrior";
m_picture = ":/images/large-warrior.png";
}
LargeWarrior::~LargeWarrior(){}
QString LargeWarrior::getName() {
return m_name;
}
QString LargeWarrior::getPicture() {
return m_picture;
}
Concrete Giant Warrior Class
giantwarrior.h - Concrete Giant Warrior header file
#ifndef GIANTWARRIOR_H
#define GIANTWARRIOR_H
#include "warrior.h"
class GiantWarrior : public Warrior {
public:
// Methods
GiantWarrior();
~GiantWarrior();
QString getName();
QString getPicture();
void setXPosition(int x);
int getXPosition();
private:
// Private Member Variables
QString m_name;
QString m_picture;
};
#endif // GIANTWARRIOR_H
giantwarrior.cpp - Concrete Giant Warrior implementation file
#include "giantwarrior.h"
GiantWarrior::GiantWarrior(){
m_name = "Giant Warrior";
m_picture = ":/images/giant-warrior.png";
}
GiantWarrior::~GiantWarrior(){}
QString GiantWarrior::getName() {
return m_name;
}
QString GiantWarrior::getPicture() {
return m_picture;
}