知识卡片

单表继承判别符字段的选择,与命名空间冲突

普通读书笔记卡

内容

单表继承把继承层次里所有类的所有域塞进一张表,加载时必须先知道该实例化哪个具体类——这靠表里一个专门的判别符域来指路,它可以存类名,也可以存一个需要额外代码翻译的编码值。存编码值的问题是:继承层次每新增一个子类,翻译代码就要跟着扩展;存类名则可以直接拿这个字符串去实例化对应的类,省了翻译这一步,代价是类名字符串比编码值占用更多空间、也不利于那些直接操作数据库表结构的外部工具理解,好处是让类结构和数据库方案的对应关系更紧密直观。单表继承还有一个容易被忽视的坑:既然所有子类的域都挤在同一张表里,所有域名共享同一个命名空间,一旦不同子类里恰好用了相同的域名就会冲突——解法是用类名作为域名的前缀或后缀,拼成复合名字来规避撞名。另外值得记住的是:不需要给整棵继承树都用同一种继承映射模式,把若干相似的子类合并进单表继承、同时给那些数据差异很大的特殊子类单独用具体表继承,是完全可行且实用的混合策略。

参考来源

- 位置:《企业应用架构模式》第二部分"模式"之"第12章 对象-关系结构模式"之"12.7 单表继承"(源文件:_epub-src/OEBPS/Text/000130.html、000131.html) - 结论依据:原文说明"数据表中有一个域用来指示应该使用哪个类。它可能是类的名字也可能是一个代码域。代码域需要用一些代码来翻译才能映射到对应的类……如果把类名嵌入到表里,那么就可以直接使用这个名字来实例化……所有的域只有一个名字空间,因此就必须保证在不同的域不能使用相同的名字。将类名作为域名的前缀或者后缀构成复合名字可以解决这个问题",直接支撑本卡结论。 - 原始内容:记住,你不需要为整个继承层次只用一种继承映射模式。将若干个相似的类映射为一张表,而对那些拥有许多特殊数据的类使用具体类继承,同样是不错的做法。