重构大型构造函数

Ada*_*rth 7 c# refactoring c#-4.0

我们在域模型中有一些对象,你可以说它们可以说是攻击性的大型构造函数,这么大,以至于IntelliSense放弃了试图向你展示它...

提示具有50个左右参数的类型,主要是值类型,一些引用类型:

public class MyLegacyType
{
    public MyLegacyType(int a1, int a2, int a3, ... int a50) // etc
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

我现在就说,没有这种类型不能改变.类型本身在逻辑上代表一个实体,这恰好是属性重的.构造此类型的调用者提供来自多个源的大多数参数,但有些是默认的.也许有一种模式可以为建筑提供资源而不是结果.

但是,可以改变的是如何创建类型.目前,我们的代码部分受到以下影响:

  • 该类型缺乏智能感知.
  • 丑陋且难以理解的代码.
  • 合并由于位置的Connascence导致的痛苦.

一个直接的答案是利用可选参数的默认值和命名参数来帮助合并.我们在某种程度上对其他类型这样做,工作正常.

然而,感觉好像这是完全重构的一半.

另一个明显的解决方案是使用具有以前构造函数参数的属性的容器类型来减少构造函数参数.这很好地整理了构造函数,并允许您在容器中嵌入默认值,但实际上将问题移到另一个类型上,并且可能与可选/命名参数用法相同.

还有Fluent构造函数的概念......在每个属性(WithIntA,WithIntB)或容器类型(WithTheseInts(IntContainer c))的基础上.就个人而言,我喜欢这种来自呼叫方的方法,但是在大型类型上它又变得冗长,感觉好像我刚刚移动了一个问题而不是解决问题.

我的问题,如果有一个埋在这个烂摊子里的是:这些问题的可行的重构策略是什么? 请通过一些相关经验,陷阱或批评来充实任何答案.我倾向于Fluent的东西,因为我认为它看起来很酷,而且非常易读且易于合并.

我觉得好像我错过了构造函数重构的圣杯 - 所以我愿意接受建议.当然,这也可能只是一个令人遗憾和不可避免的副作用,首先是拥有这么多属性的类型......

Mar*_*ell 12

显然我们这里没有太多的上下文,但是在50多个参数中,我的解释是这个类做得太多了,太复杂了.我将首先寻找将块拆分为更简单,更集中的类型的方法 - 然后每个概念的实例封装到复合类中.所以它变成:

public MyLegacyType(SomeConcept foo, AnotherConcept bar, ...)
{
}
Run Code Online (Sandbox Code Playgroud)

只有在概念之间编排所需的逻辑仍然存在MyLegacyType(任何特定的逻辑SomeConcept去那里等).

这是不同的"减少与对曾经被认为是构造函数的参数属性容器类型的构造参数",因为我们正在从根本上重组逻辑 - 不仅仅是只使用一个对象来代替构造函数的参数.