下面的“抽象工厂设计模式”实现是否正确?
#include<iostream>
using namespace std;
//Abstract Product A
class Document
{
public:
virtual void createDocument() = 0;
};
class Word: public Document
{
public :
virtual void createDocument()
{
cout<<"Document Word is created"<<endl;
}
};
class Excel : public Document
{
public :
virtual void createDocument()
{
cout<<"Document Excel is created"<<endl;
}
};
//Abstract Product B
class VideoFile
{
public:
virtual void createVideoFile() = 0;
};
class VLC : public VideoFile
{
public :
virtual void createVideoFile()
{
cout<<"VideoFile VLC is created"<<endl;
}
};
class AVI : public VideoFile
{
public :
virtual void createVideoFile()
{
cout<<"VideoFile AVI is created"<<endl;
}
};
//////////////////////////////////////////////////////////////////////
class AbstractFactory
{
public:
virtual Document* createDocFiles(string fileType) = 0;
virtual VideoFile* createVideoFiles(string fileType) = 0;
};
class ConcreteFactoryA : public AbstractFactory
{
public:
virtual Document* createDocFiles(string fileType)
{
if(fileType == "Word")
return new Word();
if(fileType == "Excel")
return new Excel();
}
virtual VideoFile* createVideoFiles(string fileType)
{
if(fileType == "VLC")
return new VLC();
if(fileType == "AVI")
return new AVI();
}
};
class ConcreteFactoryB : public AbstractFactory
{
public:
virtual Document* createDocFiles(string fileType)
{
if(fileType == "Word")
return new Word();
if(fileType == "Excel")
return new Excel();
}
virtual VideoFile* createVideoFiles(string fileType)
{
if(fileType == "VLC")
return new VLC();
if(fileType == "AVI")
return new AVI();
}
};
int main()
{
AbstractFactory *ptrAbFac = new ConcreteFactoryB();
Document *ptrDoc = ptrAbFac->createDocFiles("Excel");
ptrDoc->createDocument();
VideoFile *ptrVideoFile = ptrAbFac->createVideoFiles("VLC");
ptrVideoFile->createVideoFile();
}
答案 0 :(得分:1)
您很近,但是Abstract Product类(Document
和派生类以及VideoFile
和派生类)不应具有create方法。工厂进行创建,返回的对象应该可以使用。
这可能只是方法名称的选择不佳,但应更正以防止混淆。就您的示例而言,您可以简单地将函数重命名为DoSomething
,以便您可以调用一种方法来演示成功。示例:
class Document
{
public:
virtual ~Document() = default; // must have virtual destructor
virtual void doSomething() = 0;
};
class Word: public Document
{
public :
void doSomething() override // no need for virtual.
// override helps prevent mistakes
{
cout<<"Document Word"<<endl;
}
};
抽象产品和AbstractFactory
需要虚拟析构函数。在这里讨论原因:When to use virtual destructors?。
在派生类中,您无需重新声明方法为virtual
。一旦在基类中将方法声明为virtual
,所有覆盖将自动virtual
。另外,习惯于将override
关键字用于应重写的方法。如果接口发生更改,并且避免使用不再覆盖的方法,则对于防止错误非常有用。
别忘了delete
工厂提供的所有那些对象。 Prefer std::unique_ptr
if it is available to you.
createDocFiles
和createVideoFiles
(两个实现)均未在所有可能的路径中返回。例如:如果提供的createDocFiles
是“完美单词”,则fileType
不会返回任何内容。编译器通常会对此进行标记,但允许程序进行编译(除非您将警告设置为错误)。如果程序编译时带有警告,则很可能该程序没有执行您想要的操作。修复:
virtual Document* createDocFiles(string fileType)
{
if(fileType == "Word")
return new Word();
if(fileType == "Excel")
return new Excel();
throw std::runtime_error("Unknown file type");
}