你如何防止课程成为“依赖磁铁”和上帝课程?

时间:2009-05-22 21:39:29

标签: design-patterns refactoring

在我曾经做过的几乎每个项目中,都会有一两个具有以下属性的类:

  • 非常大,有很多成员和方法。
  • 从这个类继承的许多其他类。
  • 许多其他课程,否则取决于这门课程。

糟糕的设计,你可能会说。但在所有情况下,在设计时并非如此。这些课程随着时间的推移有机地成长,成为众所周知的“上帝阶级”。这对我在大型软件项目中的经验是如此不变,我不得不问:

  • 是否有可能以这样的方式预见可能的依赖磁铁和设计软件,以至于这类课程表现出来的可能性较小?如果是这样,具体怎么样?
  • 或者,随着时间的推移它是否只需要无情的重构?
  • 或者,是否有一些技术解决方案或设计模式可以缓解这些类引起的问题?
  • 或者,这三者的组合?

欢迎提示,经验和想法!

5 个答案:

答案 0 :(得分:8)

持续重构有助于防止这种情况发生。

此外,这是强制进行一些静态代码分析的一个地方。您可以经常查找这些类,并通过查看代码度量标准将它们标记为自动重构。

但是,我最大的建议是保持一种设计需要改变的态度,事情需要分解。通常,根据我的经验,这些课程的形成是因为人们不愿意考虑改变破损或次优的设计。保持灵活性可以更容易地防止这种情况发生。

答案 1 :(得分:7)

我认为,很多这种情况往往源于随后的设计懒惰。 “积极重构”的理念是解决这类设计问题的一个很好的解决方案。问题在于,虽然“依赖磁铁”类的初始设计是好的,但后续时间紧迫的工程师倾向于简单地将其他功能附加到该类,原因很简单,因为它可以在需要的地方(通常)使用。

很大程度上,问题与这样一个事实有关:能够处理成熟软件产品需求的设计是对不太成熟的软件产品的过度设计。所有最终都在软件产品的成熟迭代中的设计对于该产品的早期迭代来说是大量的过度杀伤;从根本上说,随着发展的继续,设计必须随时摆弄。这就是重构是必要的;随着新特性和功能开始实施,设计问题将显示出来;正如他们所做的那样,承担重新设计类交互方式的任务以及重构代码以利用它的任务至关重要。只有这样,才能保持与项目成熟度具有任何相似性的设计成熟度。

实际上,设计成熟度会随着项目的复杂性而增加;对于简单项目而言,大型复杂的设计是不合适的;就像复杂项目的大规模简单设计是不合适的一样。但由于存在不匹配,设计必须随项目一起发展。重构作为一个过程只是对这种必要性的认识。

答案 2 :(得分:3)

这一个:

  • 继承的许多其他类 这个班级

可以通过preferring composition over inheritance克服。

答案 3 :(得分:2)

我的经验是,您提出的第一个设计通常不正确,随着时间的推移,您需要重新考虑设计。当一个类开始变得太大时,通常是因为它starts to violate SRP

福勒的一些重构模式很有用。 The Extract Class重构可以提供帮助,Extract SubclassExtract Superclass也可以提供帮助。我经常发现自己正在改变继承层次结构,可能使用replace inheritance with delegation

答案 4 :(得分:0)

对我来说也是无情的重构,特别是对于持续很长时间(例如几年)的小型(即不是高度设计的瀑布)项目。

我从小做起:一点点架构,比如2到5个组件。我通过向这些组件添加代码来实现功能......当组件变得太大(这是主观的)时,我将它分成多个组件。 [''组件'我的意思是'包'或'DLL'或其他东西。]

“依赖磁铁”是一个稍微不同的问题:为了解决这个问题,我热衷于分层软件,没有层之间的循环依赖关系,有时还有一个外观层,可以将高层与低层组件隔离开来。