传递大量参数的c++设计模式
C++ Design Pattern for Passing a Large Number of Parameters
我有一个合理大小的类,它实现了几个逻辑相关的算法(来自图论)。大约需要10-15个参数作为算法的输入。这些不被算法修改,而是用来指导算法的运行。首先,我将解释实现此功能的两个选项。我的问题是这样做的常见方法是什么(无论它是或不是两个选项之一)。
当N
很大时,我个人不喜欢将这些值作为参数传递给函数,特别是当我还在开发算法时。
void runAlgorithm(int param1, double param2, ..., bool paramN);
我有一个包含算法的类Algorithm
,我有一个包含这些参数的结构体AlgorithmGlobals
。我将这个结构体传递给:
void runAlgorithm(AlgorithmGlobals const & globals);
或者我添加一个公共AlgorithmGlobals实例到类:
class Algorithm {
public:
AlgorithmGlobals globals;
void runAlgorithm();
}
那么在其他地方我将这样使用:
int main() {
Algorithm algorithm;
algorithm.globals.param1 = 5;
algorithm.globals.param2 = 7.3;
...
algorithm.globals.paramN = 5;
algorithm.runAlgorithm();
return 0;
}
注意,AlgorithmGlobals
的构造函数为每个参数定义了良好的默认值,因此只需要指定具有非默认值的参数。
AlgorithmGlobals
不是私有的,因为它们可以在runAlgorithm()
函数被调用之前被自由地修改。没有必要"保护"他们。
这被称为"参数对象"模式,这通常是一件好事。我不喜欢成员版本,特别是称它为"XGlobals",并暗示它是到处共享的。相反,参数对象模式通常涉及创建参数对象的实例,并将其作为参数传递给函数调用。
其他人已经提到参数对象,但是还有另一种可能性:使用生成器。
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();
你应该在你的设计中提出几个不同的想法:
- 参数为纯输入。
- 这些参数是针对你的算法的。
- 各参数默认值相同。
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 ¶ms) : params_(params) { }
void run();
private:
const Parameters params_; // Paramaeters don't change while algorithm
}; // is running.
这就是我的建议
我使用您已经提到的技巧:
void runAlgorithm(AlgorithmGlobals const & globals);
但是会把这个类命名为AlgorithmParams
。
命名参数习惯用法在这里可能有用。
a.runAlgorithm() = Parameters().directed(true).weight(17).frequency(123.45);
建议为什么不这样做呢:
class Algorithm {
public:
Algorithm::Algorithm(AlgorithmGlobals const & globals) : globals_(globals) {}
void runAlgorithm(); // use globals_ inside this function
private:
const AlgorithmGlobals globals_;
};
现在你可以这样使用:
AlgorithmGlobals myglobals;
myglobals.somevar = 12;
Algorithm algo(myglobals);
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 资源管理设计模式
- 用于在回调中调用解析器的设计模式
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 在这种情况下我应该使用哪种设计模式
- C++中物体改变识别的设计模式?
- 确保所有构造函数调用相同的函数 c++ 设计模式
- 需要实例化不同类/对象并在启动时确定的硬件插槽的设计模式
- 设计模式,以避免不必要地添加抽象函数以适应新功能
- 工厂设计模式优化
- 使用C++模板的数据映射器设计模式
- 为什么以及如何使用原型设计模式
- 具有多个继承共享一个资源的对象 - 寻找良好的设计模式
- 在C++中创建观察器设计模式的好方法
- 现代C++在多大程度上消除了对设计模式的需求?
- 对于存储另一个类所需信息的类,例如其构造,是否有设计模式?
- 下面抽象工厂设计模式的实现是正确的吗
- sql记录集函数的状态设计模式
- 是否有可以处理方法调用依赖关系的设计模式?
- 使用 C++ 设计模式