是否可以使用仅具有重构属性的类?

Xai*_*oft 79 c# oop refactoring

我有一个方法,需要30个参数.我把参数放到一个类中,这样我就可以将一个参数(类)传递给方法.在重构传递一个封装所有参数的对象的情况下是否完全正常,即使它包含所有参数.

McK*_*Kay 75

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

此模型的一个优点是,如果添加新参数,则类的使用者不需要仅更改以添加参数.

正如David Heffernan所提​​到的,它可以帮助自我记录代码:

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

  • 使用struct有副作用,比如复制传递语义.在做出这样的决定之前,请确保您已经意识到这一点 (28认同)
  • 如果它只包含数据成员,我更喜欢使它成为struct.使用struct给人的印象是它只是数据. (2认同)

Red*_*ter 62

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

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

或者,寻找将参数分组到更高抽象级别的对象的方法.将一堆不相关的参数转储到单个类中是IMO的最后手段.

多少参数太多了?对此有更多的想法.

  • 30个参数?我很满意,也许很不相关,也可能表明方法太长,具有很高的圈复杂性,并且是臭虫的避风港.考虑一下我们所讨论的一种方法,其行为至少有30个维度可以变化.如果有这种方法的单元测试,我不希望成为他们写TBH的人. (22认同)
  • 如果没有看到OP的代码就无法回答,但我不同意这只是因为两个值在一个方法中一起使用,它们之间有很强的关系.如果这是真的,那么OO设计最终意味着创建一个包含应用程序中使用的所有可能属性的大类. (12认同)
  • 另一种可能的情况是所有参数都是相关的,但它们的组织性很差.参数组很可能被捆绑到不同的对象中而不是零散地传递.假设我有一个方法可以对"人","地址","处方"等信息进行操作......如果每个独立的信息分别传递给我的方法,那么很容易达到30个参数. (2认同)

Car*_*ter 25

这是一个好的开始.但是现在你已经有了新课程,请考虑将代码从里到外.将将该类作为参数的方法移动到新类中(当然,将原始类的实例作为参数传递).现在你已经有一个很大的方法,单独在一个类中,并且更容易将它分成更小,更易于管理,可测试的方法.其中一些方法可能会回到原来的类,但是一个公平的块可能会留在你的新课程中.您已经超越了将参数对象引入使用方法对象替换方法.

具有三十个参数的方法是一个非常强烈的迹象,表明该方法太长且太复杂.太难调试,太难测试了.所以你应该对它做些什么,并且引入参数对象是一个很好的起点.

  • 这绝对是重要的!创建这些属性包非常有用,因为它是使用自己的方法创建新类的第一步,并且您几乎总能找到属于新类的方法 - 寻找它们!我认为这是这一组中最关键的答案,它应该接近顶端. (4认同)

Ste*_*ham 14

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

它没有真正解决的一个问题是Feature Envy.传递参数对象的类是否对另一个类的数据如此感兴趣这一事实是否表明可能将对该数据进行操作的方法移动到数据所在的位置?确定属于一起的方法和数据集合并将它们分组到类中更好,从而增加封装并使代码更加灵活.

在对行为进行多次迭代并将其操作的数据分解为单独的单元之后,您会发现您不再拥有任何具有大量依赖关系的类,这总是更好的最终结果,因为它会使您的代码更加柔顺.


Dav*_*nan 10

这是一个很好的想法,也是解决问题的一个非常常见的解决方案 超过2或3个参数的方法指数越来越难以理解.

将所有这些封装在一个类中可以使代码更加清晰.因为您的属性具有名称,所以您可以编写自我记录代码,如下所示:

params.height = 42;
params.width = 666;
obj.doSomething(params);
Run Code Online (Sandbox Code Playgroud)

当然,当你有很多参数时,基于位置识别的替代方案简直是可怕的.

另一个好处是可以在不强制改变所有呼叫站点的情况下,为接口合同添加额外的参数.然而,这并不像看起来那么简单.如果不同的呼叫站点需要不同的新参数值,那么比使用基于参数的方法更难捕获它们.在基于参数的方法中,添加新参数会强制在每个调用站点进行更改以提供新参数,您可以让编译器完成所有查找操作.


Aus*_*nen 9

Martin Fowler 在他的" 重构"一书中称之为" 引入参数对象 " .有了这个引用,很少有人会认为这是一个坏主意.


C.E*_*uis 5

30个参数很乱.我认为拥有属性的类更漂亮.您甚至可以为适合同一类别的参数组创建多个"参数类".