[英]Abstract Factory Design Pattern implementation in C++ using Qt Creator
我正在嘗試制作所有創造性的設計模式,而抽象工廠方法遇到了一些麻煩。 我通常使用Python進行編程,但是,我聽說C ++對於確實必須明確理解設計模式很有用,事實證明這是正確的,錯誤的。
我基本上是按照Tutorials Point上的指南進行操作的 。
我的問題是我將如何更改當前代碼以使用工廠生產者正確地用C ++實現抽象工廠方法,因為我認為這與導致我的問題的工廠生產者額外的抽象層有關。 我已經包含了所有代碼。
我試圖制作一個簡單的圖表來更好地解釋,但這不是最正式的UML,但實際上是我想要制作的。 我的main.cpp
文件應該更好地說明我試圖了解如何制作的功能。
附:我只是想改進求職申請,所以如果您對編寫更好的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.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;
成員和大小枚舉?
您的場景也不完全需要抽象工廠,最好使用單個通用工廠,特別是在游戲對象管理的情況下
比較QString
和nullptr
,真的嗎?
寫吸氣劑和吸氣劑-現在很酷,對吧? 我的意思是為什么要簡單地將它們公開,因為您同時具有讀寫訪問器,因此可以將它們設為私有,並編寫額外的代碼以使私有成員事實上成為公眾。 這就是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.