簡體   English   中英

使用Qt Creator在C ++中實現抽象工廠設計模式

[英]Abstract Factory Design Pattern implementation in C++ using Qt Creator

我正在嘗試制作所有創造性的設計模式,而抽象工廠方法遇到了一些麻煩。 我通常使用Python進行編程,但是,我聽說C ++對於確實必須明確理解設計模式很有用,事實證明這是正確的,錯誤的。

我基本上是按照Tutorials Point上的指南進行操作的

我的問題是我將如何更改當前代碼以使用工廠生產者正確地用C ++實現抽象工廠方法,因為我認為這與導致我的問題的工廠生產者額外的抽象層有關。 我已經包含了所有代碼。

我試圖制作一個簡單的圖表來更好地解釋,但這不是最正式的UML,但實際上是我想要制作的。 我的main.cpp文件應該更好地說明我試圖了解如何制作的功能。

抽象工廠UML圖

附:我只是想改進求職申請,所以如果您對編寫更好的SO問題,編碼風格,變量命名甚至C ++約定有任何反饋,請告訴我。

主要

main.cpp-主要實現文件

測試創建一個抽象工廠,抽象劍和抽象戰士。

#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();
}

抽象工廠類

abstractfactory.h-抽象工廠頭文件

#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抽象工廠實現文件

#include "abstractfactory.h"

AbstractFactory::~AbstractFactory(){}

工廠生產者類

factoryproducer.h-工廠生產者頭文件

#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-工廠生產者實施文件

#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;
}

抽象戰士類

warrior.h-抽象的Warrior頭文件

#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 getName() = 0;
    virtual QString getPicture() = 0;
};

#endif // WARRIOR_H

warrior.cpp-抽象Warrior實現文件

#include "warrior.h"

Warrior::~Warrior(){}

抽象劍類

sword.h-抽象劍頭文件

#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-抽象劍實現文件

#include "sword.h"

Sword::~Sword(){}

混凝土TinySword類

tinysword.h-具體小劍頭文件

#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-具體的小劍實現文件

#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;
}

混凝土普通劍

normalsword.h-具體的普通劍頭文件

#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-具體的普通劍實現文件

#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;
}

混凝土大劍類

largesword.h-具體的大劍頭文件

#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-具體的大劍實現文件

#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;
}

混凝土巨劍班

Giantsword.h-具體巨劍頭文件

#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-具體巨劍實現文件

#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;
}

混凝土小戰士類

tinywarrior.h-混凝土小戰士頭文件

#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-具體的小戰士實現文件

#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;
}

混凝土普通武士階層

normalwarrior.h-具體的普通戰士頭文件

#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具體的法線戰士實現

#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;
}

混凝土大戰士類

largewarrior.h具體的大戰士頭文件

#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具體的大戰士實現文件

#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;
}

混凝土巨人戰士班

Giantwarrior.h-具體的巨型勇士頭文件

#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-具體的巨型勇士實施文件

#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;
}

顯然,我無法談論您潛在的未來雇主,但個人不會對您產生的代碼感到興奮。 不管它是否按預期工作,它都有很多問題:

  • 它太冗長,太多的代碼卻很少執行,這有幾個含義-您浪費了開發人員的時間,生成的代碼不夠簡潔,難以維護

  • 類似cout<<tinySword->getName().toStdString()<<endl; -不要這樣做,請使用空格鍵

  • 要么使用Qt要么使用std:: -混合兩者,進行冗余轉換等都沒有意義

  • 您的代碼涉及大量的字符串比較,這些比較慢的操作,最好在可能的情況下最好避免,如果您使用的是模塊化插件體系結構,則字符串才有意義,在這種情況下,插件實現了內核中不存在的類型,但是不在您的特定情況下

  • 我們真的需要為每個微小的變化單獨設置類嗎? 小劍,大劍,大劍? 只是一個具有很好uint size; Sword類呢uint size; 成員和大小枚舉?

  • 您的場景也不完全需要抽象工廠,最好使用單個通用工廠,特別是在游戲對象管理的情況下

  • 比較QStringnullptr ,真的嗎?

  • 寫吸氣劑和吸氣劑-現在很酷,對吧? 我的意思是為什么要簡單地將它們公開,因為您同時具有讀寫訪問器,因此可以將它們設為私有,並編寫額外的代碼以使私有成員事實上成為公眾。 這就是OOP的全部內容……與流行的看法相反,我要說的是,寫setter和getter僅在涉及比直接成員訪問更大的復雜性時才是合理的。

  • 您只有名稱和圖片的獲取器,這意味着它們是靜態構造。 在這種情況下,為什么還要將它們存儲為成員變量? 不必要的內存開銷?

看來您的長城牆可以輕松地簡化為功能相同,性能更好,可讀性和可維護性更高的東西。

TutorialsPoint提供的示例具有誤導性。 例如,如果調用createSword,WarriorFactory會返回什么? 由於以下原因,不能返回nullptr:

void doSomethingWithFactory(AbstractFactory* f)
{
    Warrior* w = f->createWarrior();
    Sword* s = f->createSword();
}

實際上,您實際上需要知道您是否被賦予了戰士或劍廠,因此您並沒有抽象任何東西。

我編寫了一個示例,該示例使用了一個抽象的EnemyFactory來創建Monsters和Warriors。 根據具體的工廠,這些敵人是強者還是弱者。 EnemyFactory該工廠始終會創建敵人,但其屬性取決於具體工廠。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM