【问题标题】:Is it possible to have over inheritance to be lost in code?是否有可能在代码中丢失过度继承?
【发布时间】:2011-06-25 14:26:19
【问题描述】:

我目前正在开发一个 asp.net 网站,由其他人完成,而且它的功能非常复杂......嗯,我想是的!几乎每个类都继承自另一个类,然后是另一个类,依此类推……你必须平均达到 8/10 级才能获得基类,有时甚至更多!这些类还有其他类,它们遵循相同的 Uber Inheritence 模式。 这让我多次迷失在代码中,导致上帝知道在 Visual Studio 上打开了多少个选项卡。

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

谢谢!

【问题讨论】:

  • 另一个建筑宇航员? (joelonsoftware.com/articles/fog0000000018.html)
  • 是的,这听起来像是很糟糕的代码,不管听到它有多舒服。现在,也许您想问一个关于如何将其重构为不那么讨厌的问题?
  • 所有课程的文档都足够了吗?他们有像样的命名吗?“顶级”类很容易使用吗?
  • 在很多 GUI 框架中,您可以获得多层次的继承。只看 WPF 的层次结构,我可以看到几个类从 C# 对象深入 8 级。
  • @Jimmy:你认为这意味着什么? (提示:确实意味着 8 级继承是好的设计!)

标签: c# asp.net oop


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 是的,毫无疑问,sapghetti 仓库和类被抽象到了荒谬的程度!感谢您的反馈!
【解决方案2】:

有一个关于继承的“优先组合优于继承”的设计指南 8-10 级在某种程度上打破了这一点。

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

【讨论】:

    【解决方案3】:

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

    经典的说法是继承描述了一种“is-a”关系,通过沿着继承链往上走,我们达到了更高层次的抽象。

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

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

    总结一下

    • “can-act-as”关系通常就足够了 - 然后您就不需要寻求“is-a”关系了
    • 继承槽很珍贵 - 只能使用一次。
    • 代码重用的方法远不止从类继承
    • 基类和接口是抽象:确保您的代码确实可以使用它们。如果您的接口仅由一个类实现,那么您的抽象可能毫无价值,并且在必要时很容易引入。
    • 如果需要抽象,则接口上的惩罚要低于基类。

    【讨论】:

      【解决方案4】:

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

      这些是什么类?控制?业务对象?它们是否记录在任何地方 (UML),以便您可以很好地了解模型?

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

      【讨论】:

        【解决方案5】:

        当然,我最近一直在挖掘继承地狱。我们确实有这样的代码

         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 建模工具,它可以对你正在使用的语言进行逆向工程。

        【讨论】:

        • 问题标记为 C#,这就是应用 C# 语法突出显示的原因。
        • 没问题!您可以通过在代码块前添加 HTML 注释来指定语言,例如 <!-- language: VB -->
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-14
        • 2020-01-25
        相关资源
        最近更新 更多