【问题标题】:Has inheritance become bad?继承变坏了吗?
【发布时间】:2010-05-20 12:29:42
【问题描述】:

我个人认为继承是一个很好的工具,如果应用得当,可以大大简化代码。

但是,在我看来,许多现代工具不喜欢继承。让我们举一个简单的例子:将一个类序列化为 XML。一旦涉及到继承,这很容易变成一团糟。尤其是当您尝试使用基类序列化程序序列化派生类时。

当然,我们可以解决这个问题。类似于KnownType 属性之类的东西。除了在你的代码中你必须记住每次添加派生类时都要更新之外,如果你从你的范围之外收到一个在编译时不知道的类,那也会失败。 (好吧,在某些情况下,您仍然可以解决这个问题,例如在 .NET 中使用 NetDataContract 序列化程序。这肯定是一个进步。)

无论如何,基本原则仍然存在:序列化和继承不能很好地混合。考虑到在过去十年中变得可能甚至很常见的大量编程策略列表,我很想说在与序列化相关的领域(特别是远程处理和数据库)应该避免继承。

这有意义吗?还是把事情搞砸了?你如何处理继承和序列化?

【问题讨论】:

  • 这是否是另一个更喜欢组合而不是继承的原因?
  • 我相信组合和继承各有各的应用。如果继承是两者中更好的选择,那我真的很想用它。我讨厌因为技术不支持更好的正确设计而不得不使用劣质设计。

标签: database inheritance serialization remoting


【解决方案1】:

继承和序列化确实存在一些问题。一是它导致序列化/反序列化之间的不对称。如果一个类被子类化,这将在序列化期间透明地工作,但在反序列化期间会失败,除非反序列化知道新类。这就是为什么我们使用诸如@SeeAlso 之类的标签来注释数据以进行 XML 序列化的原因。

然而,这些问题对于继承来说并不新鲜。它经常在术语开放/封闭世界下进行讨论。要么您认为您了解整个世界和课程,要么您可能会遇到第三方添加新课程的情况。在一个封闭的世界假设中,序列化不是什么大问题。在开放世界的假设中问题更大。

但是继承和开放世界假设还有其他问题。例如。如果您在类中删除 protected 方法并相应地重构,您如何确保没有第三方类在使用它?在开放的世界中,您的类的公共和内部 API 一旦提供给其他人使用,就必须被视为已冻结。您必须非常小心地改进系统。

关于序列化如何工作的其他更多技术性内部细节可能令人惊讶。这适用于 Java,但我很确定 .NET 有相似之处。例如。 Serialization Killer,作者 Gilad Bracha,或 Serialization and security manager 漏洞利用。

【讨论】:

    【解决方案2】:

    我在当前项目中遇到了这个问题,这可能不是最好的方法,但我为它和它自己的类创建了一个服务层。我认为它被命名为 ObjectToSerialized 转换器和几个接口。通常这是一对一的(“对象”和“序列化”具有完全相同的属性),因此向界面添加一些内容会让您知道“嘿,在这里也添加它”。

    我想说我有一个 IToSerialized 接口,上面有一个用于通用目的的简单方法,并在大多数转换中使用了 automapper。当然,它的代码要多一些,但不管怎样,它都能正常工作并且不会搞砸其他事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-25
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 2015-04-23
      • 1970-01-01
      相关资源
      最近更新 更多