处理大量输入参数,大量输出

时间:2008-12-08 22:24:47

标签: parameters oop

我需要执行复杂的计算。在我的例子中,创建一个Calculator类(使用策略模式抽象)似乎是最自然的。

要执行计算,类需要接受大约20个输入,其中一些是可选的,其中一些可能在将来发生变化等。一旦调用 Calculate()方法,大约20个需要输出不同的变量。

有很多方法可以实现。

  • 作为参数传入计算方法的输入
  • 通过计算器属性传入的输入
  • 将输入包装到自己的类中,然后传递给Calculate()方法。
  • Calculate()返回的输出,包含在类
  • 输出填充到传递给Calculate()方法的参数
  • 在调用Calculate()之后从计算器的公共属性中检索的输出

所有这些方法都有利弊。 你会怎么做?

更新: 感谢您的反馈。

此计算器的目的是生成报价。输入内容包括客户地址,利率,目标利润,附加费用,产品ID等。输出包括报价,实际利润,更多费用等。

我已经开始创建ICalculateInput和ICalculateOutput接口及其具体类,系统现在运行良好。 Calculator类还继承自ICalculator接口(因为所涉及的计算差别很大,具体取决于产品来源的公司)。

10 个答案:

答案 0 :(得分:4)

我建议

  • 将输入包装到自己的类中,然后传递给Calculate()方法。
  • Calculate()返回的输出,包含在类
只有在进行多步计算时,或者如果基本计算步骤可能多次执行并且重新填充输入很困难,那么

在计算器中存储状态才有意义。否则,这是一个糟糕的抽象,当你多线程或在代码的不同部分重用相同的对象时,它会失败。

有很多参数很难维护和阅读,如果你需要改变的话,它是不灵活的

改变参数以生成输出是个坏主意。从呼叫方那里看来,他所拥有的一个类已经通过将其传递给一个函数而被改变了。

答案 1 :(得分:3)

大多数人建议使用“参数类”和“结果类”。我同意这种方法,但在我看来,您的参数分为几类。也许您可以为所需参数创建参数类,并为可选参数或可选参数组创建单独的参数类。这样,您可以根据所需的计算类型创建不同的方法;

Result calculate(RequiredArgs requiredArgs) {
...
}

Result calculate(RequiredArgs requiredArgs, OptionalArgs optionalArgs) {
}

Result calculate(RequiredArgs requiredArgs, OptionalArgs optionalArgs, OtherOptionalArgs oOpitonalArgs) {
}

这将使您的API更易于使用。如果您不想为不同的组创建类,也可以使用Maps,但这需要在计算引擎中使用更多验证代码。通常我更喜欢参数类,但必须更多地了解您的特定问题才能具有决定性。

由于线程安全性和对象可重用性,我不会将计算结果存储在计算引擎本身中。维护无状态代码要容易得多。

答案 2 :(得分:1)

长参数列表变得繁重且容易出错。告诉我们关于应用程序和环境的更多信息,但一般来说,传递某个类的对象或使用列表等是很诱人的。

我所做的一个非常好的处理方法是使用Composite模式。例如,在Java中,您可以创建一个Parameter接口,然后创建一个实现Parameter的对象列表。

答案 3 :(得分:1)

根据经验,不要创建接受超过3-4个单独参数的方法

JavaScript中的

您不应该做的事

var addUser = function (name,surname, age, add1, add2, telephone) {
    //do something
};

而不是上述内容,它更好地做这样的事情:

var addUser = function (userDetails) {
    //Do something with userDetails.name etc...
};
//Then invoke the function by passing in an object:
var ud = {name : 'Andreas', surname : 'Grech', age : 20, add1 : 'bla', add2 : 'bla', telephone : 12343}; 
addUser(ud);

这样你可以通过以任何你喜欢的顺序输入参数来调用函数而不会破坏它,你甚至可以跳过一些

答案 4 :(得分:1)

我同意你的输入和输出应该包含在他们自己的类中。

如果某些或所有参数都是可选的,您可能需要考虑的一种可能性是使用Builder pattern来构造输入对象。

答案 5 :(得分:1)

你遗漏了

  • 输入到Dictionary中的输入,传递给Calculate

人们想知道为什么你有20个输入到一个功能...似乎过度。但是如果你需要它们,并且有些是可选的,并且计算方法将来可能会通过策略模式进行更改,那么传入一组命名变量可能是有意义的。您甚至可以在集合中指定策略模式,以便Calculate方法是完全通用的

答案 6 :(得分:0)

你没有提到语言,但我会假设c#。 我可能会将它们作为结构(或类)传递,并以相同的方式返回输出。

或者,我会找到一些方法来重构它并简化预期的输入/输出。

答案 7 :(得分:0)

尝试执行.net中的数据库提供程序类。

有一个参数类(带有方向的类型和值属性,即输入/输出)&将参数(参数集合)作为计算器的属性。

有关详细信息,请查看.net中的OleDBCommand / SQLCommand类,该类用于调用存储过程/函数。

答案 8 :(得分:0)

就个人而言,我会创建一个自定义输入和输出结构或类,并预填充它们,传入它们,并接收输出结构或类的返回值。

答案 9 :(得分:0)

假设你已经考虑过这一点,并确定,是的,你确实需要所有这些参数:

我很可能会使用命名参数,但我选择的语言(Perl)支持与顺序无关的命名参数。如果你没有,那么传入一个对象是下一个最佳选择。必须按特定顺序(命名与否)传递超过2-3个参数只是在寻找麻烦。

对于输出,如果有多个值返回,我很可能会返回一个对象。