C++简单工厂模式的学习

我们先从最常见的C++类的一个实现开始说起,

class API
{
public:
virtual test(std::string s)=0;
protected:
API(){};
};
class ImpleOne :public API {
public:
    void test(string s) override {
        std::cout << "现在是One在执行 " << s<<std::endl;
    }
};

int main(void)
{
API * pApi=new ImpleOne();
pApi->test();
return;
}

这样的代码就会破坏我们面向对象的封装性,因为调用者会知道API和IMPLEONE的存在。

怎么样完成高内聚,低耦合这个要求那?

那就用一下我们的简单工厂模式,在头文件中

#include<iostream>
#include<string>
#include<map>
//建立函数指针 
typedef void* (*Constructor)();

//创建一个工厂.
class CObjectFactory
{
public:
    //注册对应的类添加到容器中
    static void RegsiterClass(std::string classname, Constructor constructor)
    {
        constructors()[classname] = constructor;
    }
    //创建一个类的对象并返回
    static void* CreateObject(const std::string ClassName)
    {
        Constructor constructor = nullptr;
        if (constructors().find(ClassName) != constructors().end())
        {
            constructor = constructors().find(ClassName)->second;
        }
        if (constructor == nullptr)
        {
            return nullptr;
        }
        return (*constructor)();
    }
private:
    //返回一个容器
    static std::map<std::string, Constructor>& constructors()
    {
        static std::map<std::string, Constructor> instance;
        return instance;
    }

};

//注册我们的类的宏定义
#define REG_CLASS(class_name) \
 class class_name##Helper{ \
 public:  \
    class_name##Helper(){ \
    CObjectFactory::RegsiterClass(#class_name,class_name##Helper::CreateObjFunc); \
    }; \
    static  void*CreateObjFunc() \
    { \
        return new class_name; \
    } \
 };\
 static class_name##Helper class_name##helper; //加入static是指只在头文件中有效。

然后就是如何调用这个简单工厂

 //在这里可以通过读取配置文件,或者直接修改REG_CLASS和CreateObject中的字符串,就可以完成对这个类的改变,或者更新 ,并不影响后面代码的更改。
 REG_CLASS(ImpleOne)
 class AUTOFACTORY
 {
     public:
     std::shared_ptr<Api> CreateAPI()
     {
        
        std::shared_ptr<API> Apipointer(static_cast<API*>(CObjectFactory::CreateObject("ImpleOne")));
        return Apipointer;
     }
 }
 int main(void)
 {
    std::shared_ptr<Api> testpoint(AUTOFACTORY::CreateAPI());
    testpoint->test("我不是你爸爸!");
    return;
 }

总结一下:我们可以通过创建一个类作为工厂提供我们所需要的类,并且通过一个辅助注册的类,使我们需要的类注册到我们的工厂里面,我们的调用者可以不通过知道我们类中的具体实现,就可以获取到他们所需的类,并且完好的实现了类的封装性.我们在以后修改或者替换我们的类的时候就不会影响调用者的代码。

posted @ 2019-09-24 16:24  飘雨的河  阅读(300)  评论(0编辑  收藏  举报