问题 是否有可能在代码中丢失过继承?


我目前正在开发一个asp.net网站,由其他人完成,而且它的工作非常复杂......我想是的!几乎每个类都继承自另一个类,然后是另一个类,另一个继续等等.......你必须平均大约8/10级才能获得基类,有时甚至更多!而这些类中还有其他类,它们遵循相同的Uber Inheritence模式。 这让我在代码中丢失很多次,导致上帝知道在visual studio上打开了多少个标签。

这是好的/正常的做法还是不好的做法?我觉得这是一个糟糕的做法,因为如此简单的事情变得过于复杂,过度使用继承导致不可扩展的代码...............但我可能是错的:)

谢谢!


10635
2018-02-11 14:26


起源

另一个建筑宇航员? (joelonsoftware.com/articles/fog0000000018.html) - Sébastien Nussbaumer
是的,这听起来像是糟糕的代码,无论听到什么安慰都是如此。现在,也许你想问一个关于如何将它重构成一些不那么讨厌的东西的问题? - Jerry Coffin
文档是否足以满足所有课程的需要?他们是否有合适的命名,并且“顶级”类很容易使用? - CodingBarfield
在许多GUI框架中,您可以获得多个级别的继承。只是看看WPF的层次结构,我可以看到几个从C#Object深入8级的类。 - Jimmy
@Jimmy:你觉得这意味着什么? (提示:确实如此 不 意味着8级继承是好的设计!) - Jerry Coffin


答案:


是的,过度使用继承可能会导致意大利面条仓库。继承是一种允许封装和抽象的工具。滥用它会导致过多的抽象,然后代码的目的变得无法使用。我已经看到这种模式在命令式构造中被滥用,其中方法在实际应用动作之前从方法传递到方法。

private bool getData()
{
    return getOtherData();
}

private bool getOtherData()
{
    return getSomeExtraData();
} 

private bool getSomeExtraData()
{
    return SeeHowTediousThisIs();
}

这一切都有效,但它只是一个非常糟糕的维护架构。我发现这经常发生在试图引入复杂性的顾问/承包商(re:工作保障)。


8
2018-02-11 14:31



是的,肯定的sapghetti仓库和课程已经过度抽象到一个荒谬的程度!感谢您的反馈意见! - Funky


有一个设计指南“有利于继承”,8-10级继承中断。

http://en.wikipedia.org/wiki/Composition_over_inheritance


5
2018-02-11 14:30



是的,我已经在头部设计模式中读到了这一点 - Funky


继承作为重用代码的手段确实是一个非常糟糕的选择。考虑到基于.NET的语言中的每个类都有一个  代码可以继承的继承槽。因此,对于每个类,应该明智地选择它是否应该继承其他东西。

经典地说,继承描述了一个 “是一个” 关系,通过上升继承链,我们达到更高的抽象水平。

第一个问题应该始终是a “能-ACT-作为” 关系不够。在这种情况下,通过描述关系 接口 通常是更好的选择。其次,在添加抽象时,问题必须是不可忽略的代码量是否可以与这些抽象一起使用以满足您正在寻找的功能。

如果几乎没有任何代码使用这些抽象,那么它们本身很可能毫无价值。同样,接口的抽象成本通常低于基类。

所以,总结一下

  • 一个“可以行为”的关系通常就足够了 - 你就不需要去寻找“是一个”的关系
  • 继承槽很珍贵 - 它只能使用一次。
  • 代码重用的方法比继承类的方法多得多
  • 基类和接口是抽象:确保您的代码确实可以使用它们。如果您的接口只由一个类实现,那么您的抽象可能毫无价值,并且在必要时可以轻松引入。
  • 如果需要抽象,则接口上的惩罚低于基类。

1
2017-08-02 17:02





听起来像继承过度,很少需要超过2-3级,这将是一个复杂的商业模式。

这些课程是什么类型的?控制? Business Objects?它们是否记录在案(UML),以便您可以很好地了解模型?

8-10级深度很多,我猜测这些类是在(或从未)设计之前编码的。


1
2018-02-11 14:31





最近,我一直在挖掘继承地狱。我们确实拥有看起来像这样的代码

 Public Class A
   ' Do Stuff, methods, members, etc.
     Public var As Object

     Public Sub New()
         member = New Object
     End Sub
 End Class

 ' yes it's empty
 Public Class B : Inherits A
 End Class

 ' yes it's empty
 Public Class C : Inherits A
     Public Sub New()
         MyBase.New()
         member.SomeMethod()
     End Sub
 End Class

然后是Base类,它包含必须继承的对象列表,以便将对象添加到该列表中。

简而言之,是的,继承可以被滥用,就像所有事情一样。对我来说最大的帮助就是找到一个很好的UML建模工具,它可以对你正在使用的语言进行逆向工程。


0
2018-04-20 19:59



问题是标记为C#,这就是应用C#语法高亮的原因。 - Mathieu Guindon
为什么谢谢你,我之前没有意识到 - Apeiron
没问题!您可以通过在代码块之前添加HTML注释来指定语言,例如 <!-- language: VB -->。 - Mathieu Guindon