下面的“抽象工厂设计模式”实现正确吗?

时间:2018-07-31 18:33:49

标签: c++ design-patterns

下面的“抽象工厂设计模式”实现是否正确?

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

    }

1 个答案:

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

createDocFilescreateVideoFiles(两个实现)均未在所有可能的路径中返回。例如:如果提供的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");
        }
相关问题