在我现在创建的代码中,我有一个对象可以属于两种离散类型,通过序列号进行区分。像这样的事情:
class Chips {
public:
Chips(int shelf) {m_nShelf = shelf;}
Chips(string sSerial) {m_sSerial = sSerial;}
virtual string GetFlavour() = 0;
virtual int GetShelf() {return m_nShelf;}
protected:
string m_sSerial;
int m_nShelf;
}
class Lays : Chips {
string GetFlavour()
{
if (m_sSerial[0] == '0') return "Cool ranch";
else return "";
}
}
class Pringles : Chips {
string GetFlavour()
{
if (m_sSerial.find("cool") != -1) return "Cool ranch";
else return "";
}
}
现在,实现这一点的明显选择是使用工厂设计模式。手动检查哪个序列属于哪个类类型不会太困难。
但是,这需要有一个知道所有其他类并通过名称引用它们的类,这几乎不是真正通用的,特别是如果我最终不得不添加一大堆子类。
让事情变得更复杂的是,在知道对象的实际序列号之前,我可能必须保留一个对象一段时间,这意味着我可能必须编写充满虚拟函数的基类,而不是保持它抽象并以某种方式替换它当我得到序列号时,使用其中一个子类的实例。这也不太理想。
工厂设计模式真的是解决这个问题的最佳方法吗?还是有人有更好的主意?
最佳答案
您可以创建一个只知道基类的工厂,如下所示:
向基类添加纯虚方法:virtual Chips* clone() const=0;
并为所有派生实现它,就像 operator=
但返回指针到一个新的派生。 (如果你有析构函数,它也应该是虚拟的)
现在您可以定义一个工厂类:
Class ChipsFactory{
std::map<std::string,Chips*> m_chipsTypes;
public:
~ChipsFactory(){
//delete all pointers... I'm assuming all are dynamically allocated.
for( std::map<std::string,Chips*>::iterator it = m_chipsTypes.begin();
it!=m_chipsTypes.end(); it++) {
delete it->second;
}
}
//use this method to init every type you have
void AddChipsType(const std::string& serial, Chips* c){
m_chipsTypes[serial] = c;
}
//use this to generate object
Chips* CreateObject(const std::string& serial){
std::map<std::string,Chips*>::iterator it = m_chipsTypes.find(serial);
if(it == m_chipsTypes.end()){
return NULL;
}else{
return it->clone();
}
}
};
用所有类型初始化工厂,您可以从中获取初始化对象类型的指针。
关于c++ - 比工厂更好的设计模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19925165/