我有一个算法需要大量参数(即配置)作为其构造函数的一部分,并且还需要一些明确定义的创建步骤。因此,我创建了一个Builder Pattern实现,允许设置所需的参数并创建中间和最终实例,例如。
// somewhere
class SomeAlgo {
public:
SomeAlgo(double a, double b, double c, double d, double e /* etc */);
;
现在我将Builder定义为例如。
class SomeAlgoBuilder {
public:
SomeAlgo& createResult() { /* TODO: */ }
virtual SomeAlgoBuilder& creationStep1() = 0;
virtual SomeAlgoBuilder& creationStep2() = 0;
virtual SomeAlgoBuilder& creationStep3() = 0;
// example setter note the builder returns *this
SomeAlgoBuilder& setA(double a) { a_ = a; return *this; }
SomeAlgoBuilder& setB(double b) { b_ = b; return *this; }
// etc
};
此时一切看起来还不错,但现在我想Pull Up
构建器的SomeAlgoConfig
成为// not "is a" config but need the implementation inheritance
// >>>>>> note the need to pass SomeAlgoBuilder as template
class SomeAlgoBuilder : private SomeAlgoConfig<SomeAlgoBuilder> {
public:
SomeAlgo& createResult() { /* TODO: */ }
virtual SomeAlgoBuilder& creationStep1() = 0;
virtual SomeAlgoBuilder& creationStep2() = 0;
virtual SomeAlgoBuilder& creationStep3() = 0;
};
类,这样我就可以覆盖传递简单配置的用例一个复杂的长参数列表。这种简单的配置在Java中被称为值对象或Bean。新的Builder将是这样的:
SomeAlgoConfig
现在template<T>
class SomeAlgoConfig {
T& setA(double a) { a_ = a; return *static_cast<T*>(this); }
T& setB(double b) { b_ = b; return *static_cast<T*>(this); }
// etc
}
实施:
SomeAlgoConfig config; // <<< here it won't compile because it misses the T parameter
config.setA(a).setB(b).setC(c);
意图是这样使用的:
SomeAlgoConfig
这就是我猜的伎俩。但是,每当我想单独使用SomeAlgoConfig<SomeAlgoConfig>
时(在Builder的上下文之外),例如要将它作为参数传递我需要使用模板参数声明它,该参数本身就是template<typename T = SomeAlgoConfig> class SomeAlgoConfig
。如何以默认为模板类型的方式定义它?例如执行此操作不起作用:SomeAlgoConfig
因为此时尚不知道{{1}}。
答案 0 :(得分:1)
Config应该像参数的容器一样,因此每当您改变想要传递的参数时,就不必更改构造函数和setter。使构建器继承配置毫无意义,因为构建器不是配置,“我需要继承的方法”不是在您的设计中实现它的有效参数。您可以将配置作为构建器的成员并调用:
builder.getConfig().setA(a);
builder.getConfig().setB(b);
//...
builder.createResult();
如果您想要模板配置,您也可以制作构建器模板,例如:
template<class T>
class AlgoBuilder<T>{
//...
private:
AlgoConfig<T> config;
这样,您可以在构造函数中设置传递配置。
关于在实例化配置时遗漏T参数的问题......那么,既然你想设置a,b,c和所有其他参数,你已经知道了参数的类型,所以你实际上可以使用T类型实例化配置,这与您的参数类型相同。 AlgoConfig&LT; AlgoConfig&GT;对我没有多大意义。