改变容忍度的建议

时间:2009-12-23 22:07:15

标签: c# winforms backwards-compatibility

背景:
我将开发依赖于快速变化的API和快速变化的数据模型的工具,我将无法控制这些模型。

数据模型和API更改很常见,这里的问题是我的代码必须继续使用当前和所有过去的版本(即100%的后备词兼容性),因为所有内容都将继续使用。

当它遇到缺失/未知特征等时,它也必须优雅地降级。

这些工具将使用WinForms以C#编写,用于测试自定义硬件。

<Edit>

我的目标是接近于只需要创建类来添加功能,当数据模型发生变化时,创建一组新的数据模型类,这些类将由工厂根据API版本创建。
< / p>

我面临的挑战是,未来的功能可能取决于具体的数据模型,这些模型可以混合和匹配(直到达到最终的组合)。你会如何优雅地处理这个问题?

<Edit2>

当然,一旦产品发货,我想重复使用该工具,只需为新产品添加代码。在我开始之前,每个产品周期都意味着重写(从头开始)所有工具,我打算在将来防止这种工具:)

</Edit>

问题:
为了保持与多个版本的API /数据模型的兼容性,您会建议或成功使用哪些设计技术和模式?

我应该注意哪些陷阱?

7 个答案:

答案 0 :(得分:4)

实际上所有 SOLID 模式都适用于此处,尤其是Single Responsibility Principle(SRP)和Open/Closed Principle(OCP)。

OCP明确声明该类型应该打开以进行扩展,但关闭以进行修改 - 这听起来非常适合您的情况,因为这将是确保向后兼容性的一种方法。 / p>

SRP在这里也非常有用,因为它意味着如果一个类只做了一件事,并且那件事变得过时了,那么它就不会拖​​延很多其他问题。它可以让它自己死掉。

在更实际的层面上,我建议您遵循两个原则:

TDD(或者只是一个全面的单元测试套件)将有助于保护您免受重大变更的影响。

答案 1 :(得分:3)

一个可能有用的想法是Eric Evans在他的书Domain Driven Design中讨论的“反腐败层” - 该模式的主要动机是将您的系统与另一个系统的变化(和特性)隔离开来。

答案 2 :(得分:2)

您提到该代码用于测试自定义硬件。您的代码(即测试例程)是否也会发生变化?你的代码今天会测试一个圆圈,明天会测试一个三角形,还是每天都在进化的同一个基本圆圈?

如果事物有一个恒定的点,那么我将从那里开始,为每个版本的API和数据模型编写包装器,根据其他答案中建议的技术,链接到中心。

然而,如果没有恒定的点,一切都会移动,那么我会放弃这个项目!它无法完成!

答案 3 :(得分:1)

您的API /数据模型是否为您提供元数据?如果是这样,最好使用它来使代码尽可能独立于API更改。例如,如果您有机会通过使用数据模型架构一般生成数据模型访问例程,则应执行此操作。当然,这只适用于某些类型的操作。

答案 4 :(得分:0)

编写自己的包装器,以便代码与您无法控制的内容之间的接口。然后,您可以针对包装器公开的API编写代码,并且只需要担心包装器本身的互操作。

答案 5 :(得分:0)

您最好的办法是让您公开的API需要一个版本号来处理请求。这样您就可以选择要创建的正确对象。最糟糕的情况是,每一个变化都是破碎的,你最终会得到几十个课程。最好的情况是你的设计可以处理它,你不时会最终得到单独的类。继承可能是你的朋友。如果您需要与快速变化的API保持100%的兼容性,那么最重要的是你已经搞砸了。你最终会得到一个巨大的不可维护的类,或者几个能够正确响应版本的类。

答案 6 :(得分:0)

1)大量的单元测试。

无论何时编写一段代码,都要为未来版本必须通过的代码发布大量单元测试才能签入。

确保测试基于功能要求,即不是如何编写函数,而是为了不破坏其他代码必须做的事情。

这将有助于人们检查破坏其他代码的更改。

2)要求所有API和数据模型的正式规范。这样可以确保它们的设计更加谨慎,并且在没有想法或理由的情况下,不会发生变化。