0

我有一个算法,它需要大量参数(即配置)作为其构造函数的一部分,并且还需要一些明确定义的创建步骤。因此,我创建了一个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类中,这样我还可以涵盖传递简单配置而不是复杂的长参数列表的用例。这种简单的配置在 Java 中被称为值对象或 Bean。新的 Builder 将是这样的:

// 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;
};

现在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(在 Builder 的上下文之外)例如将其作为参数传递时,我需要使用本身的模板参数来声明它SomeAlgoConfig<SomeAlgoConfig>。如何以默认为模板类型的方式定义它?例如,这样做是行不通template<typename T = SomeAlgoConfig> class SomeAlgoConfig的:因为SomeAlgoConfig那时还不知道。

4

1 回答 1

1

Config 应该像一个参数的容器,因此当您改变对要传递的参数的想法时,您不必更改构造函数和设置器。让 builder 继承配置没有任何意义,因为 builder 不是配置,并且“我需要继承的方法”不是在您的设计中实现这一点的有效参数。您可以使 config 成为构建器的成员并调用:

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< AlgoConfig> 对我来说没有多大意义。

于 2013-10-03T18:55:12.090 回答