2009-12-29 99 views
10

在我工作的项目中,我们处理医疗帐单。支持向后兼容的类版本化

每次国家对官方表格(我们的数据类表示)进行更改时,为了保持与以前表格的向后兼容性,我们添加了新的属性,但保留了旧的属性,并且保留了旧的属性,并且拥有文档版本属性,用于确定完成了哪些验证以及用于显示它的UI操作。

这导致项目生命周期中的类型臃肿(近5年的国家授权更改),并且根本不支持旧文档格式不是一种选择。

我想尝试为每个文档版本创建一个新类,但即使如此,我们仍然会有几个非常相似(尽管稍有改动)的代码副本。而诸如ProgressNoteV16,ProgressNoteV17等类名称看起来很可怕。

继承无法使用,因为这仍然会导致相同的问题(具有不再需要的属性的类)。接口会使接口臃肿,这不会解决问题。

用于解决此问题的解决方案和最佳实践是什么?

回答

7

对于以任何身份与公众一起工作的任何机构来说,这是一个相当经典的问题,特别是在政府或政府监管机构的情况下。解决方案不是微不足道的,它可能需要一些重要的工作来创建,以及事后维护。

在过去,当我为客户处理类似问题时,这对我来说很有效,但它可能不适用于您,但您需要起草您尝试完成的内容,以及是否有意义执行此操作。

有一对夫妇的模式来熟悉(如果你的arent的话):

  1. Factory这已是前面提到的
  2. Composition希望这将让你出的一些丑陋的遗传问题
  3. Template用于分离出表格与版本之间的逻辑关系

有两本书是为解释这些相当不错(和一些其他有用的):

  1. Head First设计模式(不记得了我的头顶部)企业应用架构的
  2. 模式(福勒)

我们我已经在过去使用的过程:

  1. 开始采取所有当前的版本形式,将它们分成不同的类别并寻找共同的重叠。您可以在草稿模式下或按照您当前的计划对每个版本使用不同的类别
  2. 从此类结构衍生出许多“基本”对象,您可以将它们用作每个重要版本集的继承根表单。你可能有其中几个,但它们应该少于你的总表单对象。
  3. 现在,在每个这些基础对象中,将通用功能(即名称和地址结构等)组合在一起并将其抽象到其自己的类层次结构中,通过构造函数注入将此hieararchy注入到基类中。
  4. 现在将组合模式应用到您的基类层次结构中,并努力获得尽可能多的常见类结构。理想情况下,此时您的表单将只是在每个表单中发生更改的最小功能,并且具有一个构造函数,可以使用所有常见(也许稍有不同)的功能。
  5. 现在应用模板模式从您的类中抽象出所有常见“功能”,例如常见验证和持久性逻辑,再次使用构造函数注入以将此功能返回到您的基类中。从基类
  6. 提取接口适配器定义和使用这些为基础,您的应用程序在你的表单工作
  7. 建立你的工厂类来处理这一设置的所有蹩脚的工作。

希望能给你一些想法。

+0

谢谢你,我们有因道路潜力大修重新思考我们的设计能力,联邦政府正在做的事情。这个大纲将大大有助于探索可能性。 – 2009-12-29 21:21:10

+0

NP。祝你好运。如果您有能力接触到一些其他机构如美国国土安全部(人类服务)或DIS(移民局)他们有大规模这个问题,或许能为您提供一些好的信息。 – GrayWizardx 2009-12-29 21:51:06

+0

我碰到这来是因为我开始看到“日期”出现在我们的类名,即ClassA的,ClassA20100901,ClassA20101201。有人向我解释为:ClassA的有效期/使用,直到9月1日,然后Class20100901将被使用,然后在12月1日最后一堂课变得活跃。这是一种巨大的气味,有些事情是错误的。我会消化这个并且向团队提出这个建议。我会提供一个答案,如果我们找到任何提示。谢谢! – 2010-08-05 19:21:47

2

如果由于文档中的字段可以被删除而无法使用继承,那么目前如何处理?

根据您的设计细节,您应该能够覆盖当前版本文档未使用的字段(即覆盖该文档的子类),并在该方法的实现中引发NotSupportedException或类似事件如果表单试图分配一个值。通过类似的逻辑,你可以(也可能应该)使用接口......只是知道一个具体的实现可能会为它实现的一个属性抛出一个异常,但是这个属性并没有为该UI的版本定义。

您可以使用Factory Pattern为给定的表单版本返回适当的对象实例。

如果代码之间存在一些共同点,但代码稍有变化但大多相同,则可以将某些共同性重构为由多个公共方法使用的私有/受保护方法。

至于类命名,如果使用Factory Pattern,则可以使用该接口在大多数代码中引用该类。只有工厂本身需要处理“奇怪”的类名称。

+0

“如果由于文档中的字段可以被删除而无法使用继承”,那么目前该如何处理?“ 那将不能解决的有太多的特性(从留在向后兼容以前的版本) – 2009-12-29 20:45:06

+0

工厂模式似乎像一个合理的解决方案类的问题,因为数据绑定接受字符串将不会有强类型编译器错误...... – 2009-12-29 20:47:21

+0

@Aequitarum:UI的特定版本大概不会绑定到不适合该版本领域具有特定版本的子类,抛出一个NotImplementedException如果一个这样的属性由UI绑定到所有帮助后。赶这样的问题早。 – 2009-12-30 00:49:55

0

我会以一种更松散耦合的方式来实现它 - 一个包含两个字段的类:一个版本和一个字典。当数据发生变化时,尝试跟踪丢失和添加的属性变得非常繁琐。使用字典,您可以简单地测试以查看密钥是否存在。