有一个只有属性重构的类可以吗?

我有一个方法,需要30个参数。 我把参数放到一个类中,这样我就可以传入一个参数(类)到方法中。 在重构的情况下传递一个封装所有参数的对象是完全没问题的,即使它包含了所有的参数。

这是一个好主意。 例如,数据合同通常是如何在WCF中完成的。

这个模型的一个优点是,如果你添加一个新的参数,类的使用者不需要改变只是添加参数。

正如David Heffernan所提​​到的,它可以帮助自己logging代码:

FrobRequest frobRequest = new FrobRequest { FrobTarget = "Joe", Url = new Uri("http://example.com"), Count = 42, }; FrobResult frobResult = Frob(frobRequest); 

虽然这里的其他答案正确地指出,传递一个类的实例比传递30个参数要好,但请注意,大量的参数可能是潜在问题的症状。

例如,很多时候静态方法的参数数量会增加,因为它们应该一直是实例方法,并且您传递了很多可以在该类的实例中更容易维护的信息。

或者,请查找将参数分组到较高抽象级别的对象中的方法。 将一堆无关的参数转储到一个类中是IMO的最后一招。

看看有多less个参数太多? 对此有更多的想法。

这是一个好的开始。 但是现在你已经有了新的课程,考虑把你的代码从头到脚地翻出来。 移动将该类作为参数的方法移动到新类中(当然,将原始类的实例作为parameter passing)。 现在你已经有了一个很大的方法,只有在一个class级中,将它分成更小,更易于pipe理和可testing的方法会更容易。 这些方法中的一些可能会回到原来的类,但一个公平的块可能会留在你的新类。 您已经超越了将参数对象引入到使用方法对象replace方法 。

有三十个参数的方法是一个很强的信号,表明这个方法太长太复杂了。 太难debugging,太难testing。 所以你应该做一些事情,介绍参数对象是一个很好的开始。

虽然重构参数对象本身并不是一个坏主意,但它不应该被用来隐藏需要从其他地方提供的30个数据的类仍然是代码味道的问题。 引入参数对象重构可能应该被视为在更广泛的重构过程中的一个步骤,而不是该过程的结束。

其中没有真正解决的关注之一是Feature Envy。 传递参数对象的类是否对另一个类的数据非常感兴趣的事实并不表示可以将对这些数据进行操作的方法移动到数据所在的位置? 确定属于一组的方法和数据集合并将它们分组到类中确实更好,从而增加了封装并使代码更加灵活。

经过几次重复的分离行为和数据操作后,您将发现不再有任何具有大量依赖的类,这总是一个更好的最终结果,因为它会使您的代码更加灵活。

这是一个很好的主意,也是一个非常普遍的问题解决scheme。 超过2或3个参数的方法会以指数级的方式难以理解。

将所有这些封装在一个类中,代码更加清晰。 因为你的属性有名字,所以你可以这样编写自我logging的代码:

 params.height = 42; params.width = 666; obj.doSomething(params); 

当然,当你有很多参数的时候,基于位置识别的select是非常可怕的。

另一个好处是可以在接口协议中添加额外的参数,而不必在所有呼叫站点强制更改。 然而,这似乎并不总是微不足道的。 如果不同的呼叫站点对新参数要求不同的值,则比使用基于参数的方法更难追捕它们。 在基于参数的方法中,添加一个新参数会在每个调用站点强制更改以提供新参数,您可以让编译器完成全部工作。

马丁·福勒(Martin Fowler)在他的着作“ 重构”(Refactoring)中将这个引入参数对象称为“ 有了这个引用,很less有人会说这是一个坏主意。

30个参数是一团糟。 我觉得有一个类的属性是更漂亮的。 您甚至可以为适合相同类别的参数组创build多个“参数类”。

你也可以考虑使用结构而不是类。

但是你想要做的是非常普遍而且很棒的主意!

无论是否重构,使用Plain Old Data类都是合理的。 我很好奇你为什么认为它可能不是。

也许C#4.0的可选参数和命名参数是一个很好的select?

无论如何,你所描述的方法也可以抽象出程序的行为。 例如,在一个接口中可以有一个标准的SaveImage(ImageSaveParameters saveParams)函数,其中ImageSaveParameters也是一个接口,并且可以具有其他参数,具体取决于图像格式。 例如, JpegSaveParameters具有Quality -property,而PngSaveParameters具有BitDepth属性。

这就是Paint.NET中的保存对话框,它是一个非常现实的例子。

如前所述:这是正确的一步,但也要考虑以下几点:

  • 你的方法可能太复杂了(你应该考虑把它分成更多的方法,甚至把它变成一个单独的类)
  • 如果你为参数创build类,使它不可变
  • 如果许多参数可能为null或者可能有一些默认值,则可能需要为您的类使用构build器模式 。

这里有很多很好的答案。 我想补充我的两分钱。

参数对象是一个很好的开始。 但是还有更多可以做的事情。 考虑以下(ruby的例子):

/ 1 /而不是简单地分组所有的参数,看看是否有可以有意义的分组参数。 您可能需要多个参数对象。

 def display_line(startPoint, endPoint, option1, option2) 

可能成为

 def display_line(line, display_options) 

/ 2 / Parameter对象可能具有比原始参数数量less的属性数量。

 def double_click?(cursor_location1, control1, cursor_location2, control2) 

可能成为

 def double_click?(first_click_info, second_click_info) # MouseClickInfo being the parameter object type # having cursor_location and control_at_click as properties 

这样的使用将帮助您发现为这些参数对象添加有意义的行为的可能性。 你会发现,他们摆脱了他们最初的Data Class气味,以尽可能舒适。 : – )