工厂设计模式优化
Factory design pattern optimization
我在Creation.cc和Creation.h中都有一个名为Creation
的class,还有一堆createA
,createB
, createC
...等这个 class 中的函数,它们都将 return 一个指针类型。
我有很多modelA.cc、modelB.cc、modelC.cc ...等等。文件,所有文件都包含 Creation.h.
由于每当我制作一个新的模型x(制作一个新的modelx.cc)时,我需要在Creation.h中添加相应的createx
,这将使所有model.cc 文件正在重新编译。
所有createA
、createB
、createC
函数的参数列表相同,但输入值和实现不同,这是基于它们的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。
有多种模式可以扩展这个主题。
我在Creation.cc和Creation.h中都有一个名为Creation
的class,还有一堆createA
,createB
, createC
...等这个 class 中的函数,它们都将 return 一个指针类型。
我有很多modelA.cc、modelB.cc、modelC.cc ...等等。文件,所有文件都包含 Creation.h.
由于每当我制作一个新的模型x(制作一个新的modelx.cc)时,我需要在Creation.h中添加相应的createx
,这将使所有model.cc 文件正在重新编译。
所有createA
、createB
、createC
函数的参数列表相同,但输入值和实现不同,这是基于它们的model.cc.
我的目标是在添加新的createx
函数时不想重新编译所有model.cc。
谢谢。
一个常见的策略是让工厂包含一个注册方法。注册 class 后,将调用工厂以获取实际实例。
下面的 C++17 示例允许 'interface' 的子 classes 在创建调用中具有不同的参数。 'createInstance' 的任务是为特定的 class.
构造一个实例Any class 取自
#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。
有多种模式可以扩展这个主题。