dimanche 2 avril 2017

Abstract Factory Design Pattern implementation in C++ using Qt Creator

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 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.

abstract factory diagram

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

#include "dialog.h"
#include "abstractfactory.h"
#include "sword.h"
#include "warrior.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:
    // 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 <QString>

class FactoryProducer {
public:
    // Methods
    FactoryProducer();
    ~FactoryProducer();
    static AbstractFactory* createFactory(QString factoryType);
};

#endif // FACTORYPRODUCER_H

factoryproducer.cpp - Factory Producer implementation file

#include "factoryproducer.h"
#include "warriorfactory.h"
#include "swordfactory.h"

FactoryProducer::FactoryProducer(){}

FactoryProducer::~FactoryProducer(){}

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 <QString>

class Warrior {
public:
    // Methods
    ~Warrior();
    virtual QString getPicture() = 0;
    virtual void setXPosition(int x) = 0;
    virtual int getXPosition() = 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 <QString>

class Sword {
public:
    // Methods
    ~Sword();
    virtual QString getName() = 0;
    virtual void setName(QString name) = 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:
    // Methods
    TinySword();
    ~TinySword();
    QString getName();
    void setName(QString name);
    QString getPicture();
private:
    // 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;
}

void TinySword::setName(QString name) {
    m_name = 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:
    // Methods
    NormalSword();
    ~NormalSword();
    QString getName();
    void setName(QString name);
    QString getPicture();
private:
    // 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;
}

void NormalSword::setName(QString name) {
    m_name = 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:
    // Methods
    LargeSword();
    ~LargeSword();
    QString getName();
    void setName(QString name);
    QString getPicture();
private:
    // 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;
}

void LargeSword::setName(QString name) {
    m_name = 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:
    // Methods
    GiantSword();
    ~GiantSword();
    QString getName();
    void setName(QString name);
    QString getPicture();
private:
    // 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;
}

void GiantSword::setName(QString name) {
    m_name = 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:
    // Variables
    QString m_picture;
};

#endif // TINYWARRIOR_H

tinywarrior.cpp - Concrete Tiny Warrior implementation file

#include "tinywarrior.h"

TinyWarrior::TinyWarrior(){
    m_picture = ":/images/tiny-warrior.png";
}

TinyWarrior::~TinyWarrior(){}

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:
    // Methods
    NormalWarrior();
    ~NormalWarrior();
    QString getPicture();
private:
    // Variables
    QString m_picture;
};

#endif // NORMALWARRIOR_H

normalwarrior.cpp Concrete Normal Warrior implementation

#include "normalwarrior.h"

NormalWarrior::NormalWarrior(){
    m_picture = ":/images/normal-warrior.png";
}

NormalWarrior::~NormalWarrior(){}

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 getPicture();
private:
    // Variables
    QString m_picture;
};

#endif // LARGEWARRIOR_H

largewarrior.cpp Concrete Large Warrior implementation file

#include "largewarrior.h"

LargeWarrior::LargeWarrior(){
    m_picture = ":/images/large-warrior.png";
}

LargeWarrior::~LargeWarrior(){}

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 getPicture();
    void setXPosition(int x);
    int getXPosition();
private:
    // Variables
    QString m_picture;
};

#endif // GIANTWARRIOR_H

giantwarrior.cpp - Concrete Giant Warrior implementation file

#include "giantwarrior.h"

GiantWarrior::GiantWarrior(){
    m_picture = ":/images/giant-warrior.png";
}

GiantWarrior::~GiantWarrior(){}

QString GiantWarrior::getPicture() {
    return m_picture;
}

Aucun commentaire:

Enregistrer un commentaire