传递单个对象与传递多个参数

Ruf*_*fus 22 parameters design-patterns method-call parameter-object

假设我有以下内容

Class A {
    Foo getFoo();
    Bar getBar();
    Baz getBaz();
}
Run Code Online (Sandbox Code Playgroud)

我需要定义一个函数doStuff使用Foo,Bar,Baz一个对象,并做一些事情

我正在努力实现哪种方法doStuff更好(假设它不适合放在doStuff类中A)

方法A.

void doStuff(Foo foo, Bar bar, Baz baz)
{ 
    //some operation
}
Run Code Online (Sandbox Code Playgroud)

要么

方法B.

void doStuff(A a)
{
    Foo foo = a.getFoo();
    Bar bar = a.getBar();
    Baz baz = a.getBaz();
    //some operation
}
Run Code Online (Sandbox Code Playgroud)

据我所知,(+专业, - 缺点)

方法A.

+很清楚究竟有哪些参数可以doStuff()运行

- 易受长参数列表的影响,更容易受到用户错误的影响

方法B.

+简单易用的方法

+似乎更具可扩展性(?)

- 对课堂不必要的依赖 A


任何人都可以分享对这两种方法的利弊的额外见解吗?

Dav*_*uth 27

方法A(裸参数)总是具有以下优点

  • 它要求方法作者输入less,因为它们不必实现参数对象,
  • 它要求方法调用者输入less,因为它们不必实例化参数对象
  • 它表现得更好,因为不需要构造参数对象并收集垃圾
  • 读者可以单独从方法签名中看出各个参数是什么(但这是一把双刃剑;见下文)

方法B(参数对象)具有优势

  • 参数具有域意义作为一个组,因此可以为参数对象指定一个解释该含义的名称,从而使读者不必阅读和理解该组的每个成员以及它们之间的关系
  • 参数列表用于多个方法,因此在每个方法中使用参数对象可以减少重复
  • 参数列表中的值作为一组在多个方法中传递,当它们作为单个参数对象传递时更容易
  • 某些值组合无效; 参数对象可以防止这些组合
  • 某些值是可选的,可以由参数对象提供,而不是(取决于您的语言)默认参数值或重载方法
  • 存在多个相同类型的参数,更有可能使值交换错误(尽管如果参数对象具有与方法具有相同参数列表的构造函数,则在这种情况下不是更好)

参数对象引入了一个新的依赖关系,调用者和被调用者依赖它并不是一个缺点,因为它是一个简单的类,没有自己的依赖.

所以,参数对象是

  • 对于单个参数几乎从来没有价值,对于双参数方法有时是值得的(例如,Point通常比x,y更好),有时不会,并且对三个或更多参数越来越有帮助
  • 当更多方法使用相同的参数列表时,越来越有用


Som*_*yya 6

Parameter Object确实提供了一种很好的方法来封装related参数,以减少任何方法或构造函数的总参数数量。应该非常小心以确保参数对象确实包含真正相关的参数。

实际上,根据parameter types您要处理的问题,有多种方法可以解决此问题。如果您要处理的参数是通用类型(例如,多个Strings或Ints),并且客户端可能会传递错误的参数序列,则创建custom typesie 通常更有意义。enum用可能的值创建。这样可以为您的参数提供良好的编译时检查。它们的另一个好用法是您可以将它们用于return函数中的复杂值。看这里

我花费很多时间的另一种方法是检查并查看该doStuff方法完成的工作是否分解为具有较少依赖性的更简单方法。

原则上,我尝试遵循鲍勃·马丁(Bob Martin)关于最多三个参数的建议。好吧,他实际上说应该最多不超过一个!任何增加都应有正当理由。请参阅这本好书:清洁代码