c++ - 工厂设计模式优化
问题描述
我Creation
在 Creation.cc 和 Creation.h 中都有一个名为的类,并且有一堆createA
, createB
, createC
... 等。这个类中的函数,它们都将返回一个指针类型。
我有很多modelA.cc,modelB.cc,modelC.cc ...等。文件,并且所有文件都包含 Creation.h。
因为每当我制作一个新模型x(制作一个新的modelx.cc)时,我需要createx
在Creation.h中添加相应的,这将使所有model.cc文件重新编译。
所有createA
, createB
,createC
函数都有相同的参数列表,但输入值和实现不同,这基于它们的 model.cc。
我的目标是我不想在添加新createx
函数时重新编译所有 model.cc。
谢谢。
解决方案
一个常见的策略是让工厂包含一个注册方法。一旦注册了一个类,就会调用工厂来获取一个实际的实例。
下面的 C++17 示例允许“接口”的子类在创建调用中具有不同的参数。“createInstance”的任务是为特定类构造一个实例。
Any 类取自这里。如链接中所述, 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。
有多种模式可以扩展此主题。
推荐阅读
- javascript - 如何将文本放在文本上
- android - 如果我留下这个错误,可能会出现什么问题?java.lang.IllegalArgumentException:服务未注册:lu@5d88aef
- azure - 是否可以确定是什么阻止了等待?
- python - catchup_by_default = False 被 DebugExecutor 忽略
- overleaf - 背页中的 AutoFit 表格
- java - C++ 警告和 logj4 日志级别
- java - Kafka 生产者无法正常工作,出现错误 kafka-producer-network-thread | 生产者-1
- c++ - make_heap 内存访问问题 error: Abort (core dumped)
- excel - 在 Excel 中合并两个列表,一个在另一个之下
- javascript - 带有背景图像的滑块循环