设计模式之工厂模式

作者: coolTigers | 来源:发表于2019-12-25 23:37 被阅读0次

    工厂模式用于隔离类对象的使用者和具体类型之间的耦合关系,通过虚函数的方法将创建具体对象的动作延迟到子类,从而实现扩展而非更改的策略。


    image.png

    如上图所以,产品和工厂作为抽象类,应该是稳定的,而具体类和具体的工厂可能会随着具体业务需求进行扩展,实际工程中并不鼓励修改。

    #pragma once
    
    #ifndef FACTORY_H
    #define FACTORY_H
    #include<iostream>
    // 产品抽象基类
    class Language {
    public:
        virtual void Speak() = 0;
        virtual ~Language() {}
    };
    // 工厂基类
    class LanguageFactory
    {
    public:
        virtual Language* SpeakLanguage() = 0;
        virtual ~LanguageFactory() {}
    };
    // 产品子类
    class Chinese: public Language
    {
    public:
        void Speak() 
        {
            std::cout << "Speaking Chinese! \n" << std::endl;
        }
    };
    
    class English : public Language
    {
        void Speak()
        {
            std::cout << "Speaking English! \n" << std::endl;
        }
    };
    
    class Japanese : public Language
    {
        void Speak()
        {
            std::cout << "Speaking Japanese! \n" << std::endl;
        }
    };
    
    // 工厂子类
    class ChineseFactory : public LanguageFactory {
    public:
        virtual Language* SpeakLanguage()
        {
            return new Chinese();
        }
    };
    
    class EnglishFactory : public LanguageFactory {
    public:
        virtual Language* SpeakLanguage()
        {
            return new English();
        }
    };
    
    class JapaneseFactory : public LanguageFactory {
    public:
        virtual Language* SpeakLanguage()
        {
            return new Japanese();
        }
    };
    
    class StudySpeak
    {
    public:
        StudySpeak(LanguageFactory* _factory) 
        {
            this->factory = _factory;
        }
        ~StudySpeak();
    
    private:
        LanguageFactory* factory;
    };
    
    class Study {
    private:
        LanguageFactory* factory;
    public:
        Study(LanguageFactory* _factory)
        {
            this->factory = _factory;
        }
        void DailyStudy()
        {
            Language* lang = factory->SpeakLanguage();
            lang->Speak();
        }
    };
    #endif // !FACTORY_H
    

    上述代码中,language类是product,LanguageFactory类是Creator,Chinese类、English类、Japanese类是concreteProduct,ChineseFactory类、EnglishFactory类、JapeneseFactory类是concreteCreator。

    #include "factory.h"
    #include <iostream>
    
    int main()
    {
        LanguageFactory* factory = new ChineseFactory();
        Study s(factory);
        s.DailyStudy();
    
        return 0;
    }
    

    执行效果如下:


    image.png

    上述实现只是一种众多方法中的一种,此外还可以用如下方式进行实现:
    1、可以将Creator类声明为具体类并提供一个缺省的实现。

    // 工厂基类
    class LanguageFactory
    {
    public:
        virtual Language* SpeakLanguage()
        {
            return new Chinese();
        }
        virtual ~LanguageFactory() {}
    };
    

    缺省调用Chinese类。
    2、参数化工厂方法
    参数化采用一个标识将被创建的对象种类的参数。

    // 参数化工厂
    class LanguageFactory{
    public:
        virtual Language* SpeakLanguage(std::string language);
    };
    Language* LanguageFactory::SpeakLanguage(std::string language)
    {
        if (language == "china") return new Chinese();
        if (language == "english") return new English();
        if (language == "japen") return new Japanese();
        return 0;
    }
    

    3、使用模板以避免创建子类
    有的时候可能不想为了具体的Product对象而创建creator的子类,在C++中可以提供一个Creator的模板子类,它使用Product类作为模板参数。

    // 工厂基类
    class LanguageFactory
    {
    public:
        virtual Language* SpeakLanguage() = 0;
        virtual ~LanguageFactory() {}
    };
    template <class TheLanguage>
    class StandardLanguage:public LanguageFactory
    {
    public:
        virtual Language* SpeakLanguage();
    };
    
    template <class TheLanguage>
    Language* StandardLanguage<TheLanguage>::SpeakLanguage()
    {
        return new TheLanguage;
    }
    
    StandardLanguage<Chinese> myChinese;
    

    函数调用结果如下:


    image.png

    最好总结下使用Factory Method模式的场景:
    1、当一个类不知道或者无法完全确定所必须创建的对象类型的时候;
    这时候代码展示出扩展而非更改;
    2、当一个类希望由它的子类来指定它所创建的对象类型的时候;
    3、当类就创建对象的职责委托给多个子类中的一个,并且希望子类代理这一信息局部化的时候。
    注:本文参考了《设计模式 可复用面向对象软件的基础》中的3.3节。

    相关文章

      网友评论

        本文标题:设计模式之工厂模式

        本文链接:https://www.haomeiwen.com/subject/dcghoctx.html