工厂设计模式优化

Factory design pattern optimization

本文关键字:优化 设计模式 工厂      更新时间:2023-10-16

我在 Creation.cc 和Creation.h中都有一个名为Creation的类,并且有一堆createAcreateBcreateC...等类中的函数,它们都将返回指针类型。

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

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

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

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

谢谢。

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

下面的 C++17 示例允许"接口"的子类在创建调用中具有不同的参数。 "createInstance"的任务是为特定类构造一个实例。

任何类是从这里取的。 如链接中所述,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;
}

工厂的所有成员都将从"接口"分支。 "工厂"将允许注册尚未创建的新类。 在示例中,A 和 B 存在,但 C 不存在。 将来可以在不重新编译现有代码的情况下添加 C。

有各种各样的模式可以扩展这个主题。