|
|
1
87
最好的方法是找到将论点分组的方法。这是假设的,并且只在您最终得到多个“分组”参数时才有效。 例如,如果要传递矩形的规范,可以传递X、Y、宽度和高度,也可以传递包含X、Y、宽度和高度的矩形对象。 在重构时查找类似的内容,以便对其进行一定程度的清理。如果这些论点真的不能结合在一起,那么就开始研究你是否违反了单一责任原则。 |
|
|
2
94
我想你是说 C.* . 其中一些东西也适用于其他语言。 您有几个选项: 从构造函数切换到属性设置器 . 这可以使代码更可读,因为对于读者来说,哪个值对应于哪个参数是显而易见的。对象初始值设定项语法使这看起来很好。实现起来也很简单,因为您只需使用自动生成的属性并跳过编写构造函数。
但是,您将失去不可变性,并且您将失去确保在编译时使用对象之前设置所需值的能力。 生成器模式 .
想想他们之间的关系
我有一个PowerShell脚本,它允许我生成生成器代码来执行所有这些操作,其中输入如下所示:
所以我可以在编译时生成。
“引入参数对象”重构 . 见 Refactoring Catalog . 其思想是,您获取一些要传递的参数,并将它们放入新的类型中,然后传递该类型的实例。如果你不假思索地这么做,你最终会回到你开始的地方:
变成
然而,这种方法有最大的潜力对代码产生积极的影响。因此,继续执行以下步骤:
例如,您可能看到一些代码如下所示:
你可以拿着
这更好,但要真正利用新类型,请将比较移到新类型中:
和
现在
我们正在取得进展:实现
如您所见,引入参数对象是一个很好的开始,但它的真正价值在于它帮助我们发现了模型中缺少的有用类型。 |
|
|
3
20
如果它是一个构造函数,特别是在有多个重载变量的情况下,您应该查看构建器模式:
如果这是一个普通的方法,您应该考虑正在传递的值之间的关系,并可能创建一个传输对象。 |
|
|
4
10
这引自福勒和贝克的书:“重构”
|
|
|
5
9
经典的答案是使用一个类来封装部分或全部参数。理论上这听起来不错,但我是那种为领域中有意义的概念创建类的人,所以应用这个建议并不总是容易的。 例如,代替:
你可以使用
牛传染性胃肠炎病毒 |
|
|
6
7
我不想听起来像个聪明的裂缝,但你也应该检查一下,确保你传递的数据是正确的。 真的? 应该传递给:将东西传递给构造函数(或方法)闻起来有点像对 行为 物体的 别误会我:方法和构造函数 将 有时参数很多。但遇到这种情况时,一定要考虑封装 数据 具有 行为 相反。 这种气味(因为我们谈论的是重构,这个可怕的词似乎是合适的…)也可能被检测到用于具有很多(读:any)属性或getter/setter的对象。 |
|
|
7
7
当我看到长参数列表时,我的第一个问题是这个函数或对象是否做得太多。考虑:
当然,这个例子是故意荒谬的,但是我看到过很多真实的程序,其中的例子稍微不那么荒谬,其中一个类被用来容纳许多几乎不相关或不相关的东西,显然是因为同一个调用程序需要两者,或者是因为程序员同时想到两者。有时简单的解决方案是将类分成多个部分,每个部分都有自己的功能。 稍微复杂一点的是,当一个类确实需要处理多个逻辑问题时,比如客户订单和有关客户的一般信息。在这些情况下,为客户包装一个类,为订单包装一个类,并让他们在必要时互相交谈。因此,而不是:
我们可以:
当然,我更喜欢只取1、2或3个参数的函数,但有时我们不得不接受,事实上,这个函数需要大量的参数,而且它本身的数量并不会真正造成复杂性。例如:
是的,这是一堆字段,但我们可能要对它们做的就是将它们保存到数据库记录中,或者将它们放到屏幕上或其他类似的地方。这里的处理并不多。 当我的参数列表变长时,如果我能给字段提供不同的数据类型,我会更愿意。当我看到一个函数时,就像:
然后我看到它叫:
我开始担心了。看看这个电话,根本不清楚这些神秘的数字、代码和标志意味着什么。这只是要求错误。程序员可能很容易对参数的顺序感到困惑,并意外地切换了两个参数,如果它们是相同的数据类型,编译器就会接受它。我更愿意在所有这些东西都是枚举的地方有一个签名,所以一个调用传递的东西是type.active而不是“a”和creditwatch.no而不是“false”等。 |
|
|
8
5
如果一些构造函数参数是可选的,那么使用一个生成器是有意义的,它将在构造函数中获得所需的参数,并为可选参数提供方法,返回生成器,如下所示:
这方面的细节在有效的Java,第二版,第11页中进行了描述。对于方法参数,同一本书(第189页)描述了缩短参数列表的三种方法:
|
|
|
9
4
我将使用默认的构造函数和属性设置器。C 3.0有一些很好的语法来自动完成这项工作。
代码改进在于简化构造函数,而不必支持多个方法来支持各种组合。“调用”语法仍然有点“冗长”,但并不比手动调用属性设置程序更糟糕。 |
|
|
10
4
你没有提供足够的信息来保证一个好的答案。一个长参数列表本身并不坏。
可以解释为:
在这种情况下,您最好创建一个类来封装参数,因为您以编译器可以检查的方式为不同的参数赋予意义,并使代码更易于阅读。它还使以后的阅读和重构更加容易。
或者,如果您有:
这是一个完全不同的情况,因为所有的对象都是不同的(并且不太可能被混淆)。同意如果所有对象都是必需的,并且它们都是不同的,那么创建一个参数类就没什么意义了。 另外,一些参数是可选的吗?是否存在方法重写(相同的方法名,但不同的方法签名?)这些细节都关系到 最好的 答案是。 *属性包也可能有用,但考虑到没有给定背景,这并不是特别好。 正如你所看到的,这个问题有一个以上的正确答案。你挑吧。 |
|
|
11
3
您可以尝试将参数分组为多个有意义的结构/类(如果可能的话)。 |
|
12
2
我通常倾向于结构方法——假设这些参数中的大多数以某种方式相关,并且表示与您的方法相关的某个元素的状态。
如果参数集不能成为一个有意义的对象,这可能是一个标志
|
|
|
13
2
如果您的语言支持它,请使用命名参数并使尽可能多的可选参数(具有合理的默认值)。 |
|
|
14
1
我认为你描述的方法是可行的。当我发现一个方法有很多参数和/或将来可能需要更多的参数时,我通常创建一个shnizeparams对象来传递,如您所描述的。 |
|
|
15
1
不在构造函数中同时设置,而是通过
属性/设置器
?我见过一些使用这种方法的.NET类,例如
|
|
|
16
1
您可以用复杂度来交换源代码行。如果方法本身做的太多(瑞士刀),尝试通过创建另一个方法将其任务减半。如果方法很简单,只需要太多参数,那么所谓的参数对象就是解决方法。 |
|
|
17
1
我同意将参数移动到参数对象(结构)中的方法。不过,与其将它们全部粘贴在一个对象中,还不如检查其他函数是否使用类似的参数组。如果一个参数对象与多个函数一起使用,而您希望这些函数中的参数集一致地发生更改,那么它就更有价值。可能只是将一些参数放入新的参数对象中。 |
|
|
18
1
如果您有那么多参数,那么很可能方法做的太多,所以首先通过将方法拆分为几个较小的方法来解决这个问题。如果在此之后仍然有太多参数,请尝试将参数分组或将一些参数转换为实例成员。 喜欢小类/方法而不是大类。记住单一责任原则。 |
|
|
19
1
命名参数是消除长(甚至短)歧义的好选择(假定支持它们的语言)。参数列表,同时允许(对于构造函数)类的属性是不可变的,而不要求允许它以部分构造的状态存在。 在进行此类重构时,我要寻找的另一个选项是相关参数组,它们可以更好地作为独立对象进行处理。以前面答案中的rectangle类为例,采用x、y、height和width参数的构造函数可以将x和y分解为一个点对象,从而允许您将三个参数传递给矩形的构造函数。或者更进一步,使其成为两个参数(upperLeftPoint、lowerRightPoint),但这将是一个更激进的重构。 |
|
|
20
0
这取决于您有什么类型的参数,但是如果它们是许多布尔值/选项,那么您可以使用标志枚举吗? |
|
|
21
0
我认为这个问题与你想用课堂解决的问题有着密切的联系。 在某些情况下,一个7参数的构造函数可能表示一个坏的类层次结构:在这种情况下,上面建议的助手结构/类通常是一个好方法,但是您也倾向于以仅仅是属性包的结构负载结束,并且不做任何有用的事情。 8参数构造函数还可能表示类太通用/太通用,因此它需要很多选项才能真正有用。在这种情况下,您可以重构类或实现隐藏真正复杂构造函数的静态构造函数:例如shniz.newbaz(foo,bar)实际上可以调用传递正确参数的真正构造函数。 |
|
|
22
0
一个考虑因素是,创建对象后,哪些值将是只读的? 公共可写属性可能在构造之后被分配。 价值观最终从何而来?也许有些值确实是外部的,而另一些值实际上来自库维护的某些配置或全局数据。 在这种情况下,您可以隐藏构造函数,使其不被外部使用,并为其提供一个create函数。create函数接受真正的外部值并构造对象,然后使用仅可用于库的访问器来完成对象的创建。 如果一个对象需要7个或更多的参数来给它一个完整的状态,并且所有的参数都是真实的外部属性,那就真的很奇怪了。 |
|
|
23
0
当一个CLA有一个接受了太多参数的构造函数时,它通常是一个信号,表明它有太多的职责。它可能被分成不同的类,这些类相互协作以提供相同的功能。 如果您真的需要这么多的构造函数参数,那么构建器模式可以帮助您。目标仍然是将所有参数传递给构造函数,因此从一开始就初始化了它的状态,如果需要,还可以使类不可变。 见下文:
|
|
|
Glory Raj · 有什么方法可以使这两个块具有共同的功能吗 3 年前 |
|
|
Justin · Python自属性重命名 7 年前 |
|
|
Sabutobi · 长dict属性行的重构 7 年前 |
|
|
Falco Alexander · 简单LINQ重构/样式 7 年前 |
|
|
05bs001 · Euler 12需要优化 7 年前 |
|
|
slartidan · 如何将lambda表达式重构为方法引用? 7 年前 |
|
|
Alex · 在Java类中频繁使用与映射键相同的字符串[已关闭] 7 年前 |