工厂设计模式优化

Factory design pattern optimization

我在Creation.cc和Creation.h中都有一个名为Creation的class,还有一堆createAcreateBcreateC...等这个 class 中的函数,它们都将 return 一个指针类型。

我有很多modelA.cc、modelB.cc、modelC.cc ...等等。文件,所有文件都包含 Creation.h.

由于每当我制作一个新的模型x(制作一个新的modelx.cc)时,我需要在Creation.h中添加相应的createx,这将使所有model.cc 文件正在重新编译。

所有createAcreateBcreateC函数的参数列表相同,但输入值和实现不同,这是基于它们的model.cc.

我的目标是在添加新的createx函数时不想重新编译所有model.cc。

谢谢。

一个常见的策略是让工厂包含一个注册方法。注册 class 后,将调用工厂以获取实际实例。

下面的 C++17 示例允许 'interface' 的子 classes 在创建调用中具有不同的参数。 'createInstance' 的任务是为特定的 class.

构造一个实例

Any class 取自 。如 link 中所述,createInstance 调用非常注重与方法签名匹配的输入参数。

#include <iostream>
#include <functional>
#include <map>
#include <string>
#include <any>
#include <functional>
#include <map>
#include <string>
#include <iostream>

struct interface
{
};


template<typename Ret>
struct AnyCallable
{
    AnyCallable() {}
    template<typename F>
    AnyCallable(F&& fun) : AnyCallable(std::function(fun)) {}
    template<typename ... Args>
    AnyCallable(std::function<Ret(Args...)> fun) : m_any(fun) {}
    template<typename ... Args>
    Ret operator()(Args&& ... args) 
    { 
        return std::invoke(std::any_cast<std::function<Ret(Args...)>>(m_any), std::forward<Args>(args)...); 
    }
    std::any m_any;
};

struct factory
{
   std::map<std::string,  AnyCallable<interface>> registry;
   void registerClass(std::string const & class_name, AnyCallable<interface> function)
   {
      registry[class_name] = function;
   }

   template<typename ... Args>
   interface createInstance(std::string const & class_name, Args && ... args)
   {
      if(registry.find(class_name) == registry.end())
      {
         throw "No class found";
      }
      return registry[class_name](std::forward<Args>(args)...); 
   }
};


struct A:public interface
{
   A() 
   {
      std::cout << "Create A" << std::endl;
   }

   static interface createInstance(int t)
   {
      return A();
   } 

   static void registerWithFactory(factory& f)
   {
      f.registerClass("A",&createInstance);
   }
};


struct B:public interface
{
   B() 
   {
      std::cout << "Create B" << std::endl;
   }

   static interface createInstance(std::tuple<int, double> t)
   {
      return B();
   } 

   static void registerWithFactory(factory& f)
   {
      f.registerClass("B",&createInstance);
   }
};

int main(int argc, char* argv[])
{
    factory f;

    A::registerWithFactory(f);
    B::registerWithFactory(f);
    try {
        interface a = f.createInstance("A",1);
        interface b = f.createInstance("B",std::tuple{1,1.0});
        interface c = f.createInstance("C");
    }
    catch(...)
    {
       std::cout << "createInstance failed" << std::endl;
    }
    return 0;
}

工厂的所有成员都来自'interface'。 'factory' 将允许注册尚未创建的新 class。在示例中,A 和 B 存在,但 C 不存在。将来可以在不重新编译现有代码的情况下添加 C。

有多种模式可以扩展这个主题。