有什么更好的方法来创建一个需要很多参数的方法? (10+?)

时间:2012-03-30 14:38:53

标签: language-agnostic coding-style

我正在查看其他开发人员的一些代码,几乎哭了。在方法定义中有12个参数。根据我的经验......这不好。如果是我,我会发送某种对象。

是否有另一种/更优选的方式来做到这一点(换句话说,解决这个问题的最佳方法是什么并解释原因)?

public long Save (
    String today, 
    String name, 
    String desc, 
    int ID, 
    String otherNm, 
    DateTime dt, 
    int status, 
    String periodID, 
    String otherDt, 
    String submittedDt
)

忽略我糟糕的变量名称 - 它们是示例

5 个答案:

答案 0 :(得分:5)

这在很大程度上取决于语言。

在没有编译时类型检查的语言中(例如python,javascript等),你应该使用关键字参数(在python中很常见:你可以像传入的字典一样访问它们)或对象/词典您手动传入参数(在javascript中很常见)。

然而,你所描述的“论证地狱”有时是“使用编译时类型检查对某些语言做事的正确方法”,因为使用对象会混淆来自类型检查器的语义。然后解决方案是使用更好的语言和编译时类型检查,它允许将对象的模式匹配作为参数。

答案 1 :(得分:2)

是的,使用对象。此外,如果需要所有这些信息,该功能可能做得太多,因此请使用较小的功能。

答案 2 :(得分:1)

这取决于功能的复杂程度。如果它对每个参数做了一些非常重要的事情,它应该被拆分。如果它只是通过它们,它们应该被收集在一个对象中。但是如果它只是在表中创建一行,那就没什么大不了的。如果您的语言支持关键字参数,那么这不是一个交易。

答案 3 :(得分:1)

使用对象。

class User { ... }
User user = ...
Save(user);

它决定了添加新参数的简便方法。

答案 4 :(得分:0)

我想你遇到的问题是能够查看方法调用并知道哪个参数正在接收什么值。这是像Java这样的语言中的一个有害问题,它缺少像关键字参数或JSON哈希来传递命名参数。

在这种情况下,Builder pattern是一个有用的解决方案。这是更多的对象,总共三个,但是为您描述的问题提供了更易于理解的代码。所以这种情况下的三个对象就是这样:

  1. Thing :有状态实体,通常是不可变的(即仅限getter)
  2. ThingBuilder :工厂类,创建Thing实体并设置其值。
  3. ThingDAO :不需要使用Builder模式,但可以解决您的问题。
  4. <强>相互作用

    /* 
    ThingBuilder is a static inner class of Thing, where each of its 
    "set" method calls returns the ThingBuilder instance being worked with
    while the final "build()" call returns the instantiated Thing instance.
    */
    Thing thing = Thing.createBuilder().
                    .setToday("2012/04/01")
                    .setName("Example")
                    // ...etc...
                    .build();
    
    // the Thing instance as get methods for each property
    thing.getName();
    
    // get your reference to thingDAO however it's done
    thingDAO.save(thing);
    

    结果是您获得了命名参数和不可变实例。