传递大量参数的C++设计模式

Ala*_*ing 19 c++ algorithm parameters design-patterns function

我有一个合理大小的类,它实现了几个与逻辑相关的算法(来自图论).需要大约10-15个参数作为算法的输入.这些不是由算法修改的,而是用于指导它的操作.首先,我解释了实现这个的两个选项.我的问题是这样做的常用方法是什么(无论是否是两种选择之一).

我个人不喜欢将这些值作为参数传递给函数N,特别是当我还在开发算法时.

void runAlgorithm(int param1, double param2, ..., bool paramN);
Run Code Online (Sandbox Code Playgroud)

相反,我有一个Algorithm包含算法的类,我有一个AlgorithmGlobals包含这些参数的结构.我要么将这个结构传递给:

void runAlgorithm(AlgorithmGlobals const & globals);
Run Code Online (Sandbox Code Playgroud)

或者我在类中添加一个公共AlgorithmGlobals实例:

class Algorithm {
public:
    AlgorithmGlobals globals;
    void runAlgorithm();
}
Run Code Online (Sandbox Code Playgroud)

然后我在其他地方使用它:

int main() {
    Algorithm algorithm;
    algorithm.globals.param1 = 5;
    algorithm.globals.param2 = 7.3;
    ...
    algorithm.globals.paramN = 5;

    algorithm.runAlgorithm();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

请注意,构造函数AlgorithmGlobals为每个参数定义了良好的默认值,因此只需要指定具有非默认值的参数.

AlgorithmGlobals不是私有的,因为它们可以在runAlgorithm()调用函数之前自由修改.没有必要"保护"它们.

Ern*_*ill 12

这被称为"参数对象"模式,它通常是一件好事.我不喜欢会员版本,特别是称它为"XGlobals"并暗示它在各地共享.相反,参数对象模式通常涉及创建参数对象的实例并将其作为参数传递给函数调用.


Pét*_*rök 8

其他人提到了参数对象,但还有另一种可能性:使用Builder.

Builder允许您省略默认值适合的参数,从而简化代码.如果您要将算法与几组不同的参数一起使用,这将特别方便.OTOH它还允许您重用类似的参数集(尽管存在无意重用的风险).这(与方法链接一起)将允许您编写诸如的代码

Algorithm.Builder builder;

Algorithm a1 = builder.withParam1(1).withParam3(18).withParam8(999).build();
...
Algorithm a2 = builder.withParam2(7).withParam5(298).withParam7(6).build();
Run Code Online (Sandbox Code Playgroud)


Omn*_*ous 6

你有几个不同的想法,你应该建议你的设计:

  1. 参数纯粹是输入.
  2. 参数特定于您的算法.
  3. 参数的默认值是合理的.

class Algorithm {
  public:
    class Parameters { // Nested class, these are specific to your algorithm.
      public:
        Parameters() : values(sensible_default) { }
        type_t values; // This is all about the data.
    };

    Algorithm(const Parameters &params) : params_(params) { }

    void run();

  private:
    const Parameters params_; // Paramaeters don't change while algorithm
};                            // is running. 
Run Code Online (Sandbox Code Playgroud)

这就是我的建议.