继承变坏了吗?

时间:2010-05-20 12:29:42

标签: database inheritance serialization remoting

就个人而言,我认为继承是一个很好的工具,当合理应用时,可以大大简化代码。

然而,在我看来,许多现代工具都不喜欢继承。我们举一个简单的例子:将类序列化为XML。一旦涉及继承,这很容易变成一团糟。特别是如果您尝试使用基类序列化程序序列化派生类。

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

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

这有意义吗?或者搞砸了什么?你如何处理继承和序列化?

2 个答案:

答案 0 :(得分:2)

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

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

但继承和开放世界的假设无论如何还有其他问题。例如。如果您在类中删除了protected方法并进行相应的重构,那么如何确保没有使用它的第三方类?在开放的世界中,您的类的公共和内部 API必须被视为冻结,一旦可供其他人使用。你必须非常谨慎地发展这个系统。

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

答案 1 :(得分:0)

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

我想说我有一个IToSerialized接口,其上有一个简单的方法用于通用目的,并在大多数转换中使用了automapper。当然,这是更多的代码,但不管怎么说,它起作用,并没有搞清楚其他事情。