【发布时间】:2014-02-19 09:49:02
【问题描述】:
我想创建类似通用工厂方法的东西 - 看看这个:
template <class BaseType>
class Factory {
public:
template <class ... Args>
static BaseType* Create(const Args& ... args) {
return new DerivedType(args ...);
}
};
其中DerivedType 是从BaseType 派生并在不同位置定义的其他类型。
问题在于存储DerivedType。我想这样做,例如,像这样:
void f() {
// Derived type may have more than one constructor,
// that's why I suggest using of the variadic templates.
BaseType* ptr1 = Factory<BaseType>::Create("abc", 5, 10.);
BaseType* ptr2 = Factory<BaseType>::Create();
...
}
...
Factory<BaseType>::SetType<MyDerivedType>();
f();
Factory<BaseType>::SetType<YourDerivedType>();
f();
我可以设置不同的派生类型,但它们在编译时都是已知的。 我想不出合适的技术来做到这一点。
问题:你能推荐一个吗?
这样做的基本原理(因此,原始问题,如果有人认为问题本身就是 XY 问题) - 是一种对代码的一些棘手部分进行单元测试的能力。例如,如果我有一个代码:
...
Shuttle* shuttle1 = new ShuttleImpl("Discovery", Destination::Moon);
Shuttle* shuttle2 = new ShuttleImpl();
...
而且我不想在每次运行单元测试时都真正构建穿梭:
class Shuttle: public Factory<Shuttle> { ... }
...
Shuttle* shuttle1 = Shuttle::Create("Discovery", Destination::Moon);
Shuttle* shuttle2 = Shuttle::Create();
...
所以,在单元测试中我可以这样做:Shuttle::SetType<TestShuttle>();。
可能有更多“可测试”的类,这就是为什么我需要为所有这些类建立一个通用工厂:
class Car: public Factory<Car> { ... }
class Driver: public Factory<Driver> { ... }
...
【问题讨论】:
-
我猜测某种形式的类型擦除和模仿
std分配器的接口将是探索的方向,但不知道它是否真的可能。 -
为什么不能使用第二个模板参数,例如:
template <class Base, class Derived> class Factory;? -
@CouchDeveloper - 因为代码中可以有多个
Derived:即我可以使用完整的模拟测试相同的代码,或者使用特殊的测试类来检查方法的数量调用。 -
您不能拥有需要不同实现的 same 代码。但是,template 允许您拥有实例化为不同代码的 same 模板。正是您要查找的内容,除非我不明白您的问题。
-
@CouchDeveloper - 然后将您的解决方案作为示例代码提出,如果您误解我的问题,我会尽力向您展示。
标签: c++ unit-testing c++11 factory-pattern variadic-templates