变更容忍度的建议

发布于 2024-08-16 10:30:43 字数 679 浏览 2 评论 0原文

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

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

当遇到缺失/未知功能等时,它还必须优雅地降级。

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

<Edit>

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

对我来说,未来的功能可能取决于特定的数据模型,这可以混合和匹配(直到达到最终组合)。你会如何优雅地处理这件事?

<Edit2>

当然,一旦产品发货,我想重用该工具,只需为新产品添加代码。在我开始之前,每个产品周期都意味着重写(从头开始)所有工具,这是我将来要避免的事情:)

</Edit>

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

我应该注意哪些陷阱?

Background:
I will be working on tools that will be dependent on a rapidly changing API and rapidly changing data model over which I will have zero control.

Data model and API changes are common, the issue here is that my code must continue to work with current and all past versions (ie 100% backwords compatibility) because all will continue to be used internally.

It must also gracefully degrade when it runs into missing/unknown features etc.

The tools will be written in C# with WinForms and are for testing custom hardware.

<Edit>

My goal would be something close to only having to create classes to add features and when data model changes come, create a new set of data model classes that will get created by a factory based on API version.

The challenge for me is that future features then may depend on the specific data models, which may be mixed and matched (until a final combo is reached). How would you handle this gracefully?

<Edit2>

Of course, once a product is shipped, I would like to reuse the tool and just add code for newer products. Before I started here, every product cycle meant rewriting (from scratch) all the tooling, something I aim to prevent in the future :)

</Edit>

Question:
What design techniques and patterns would you suggest or have had success with to maintain compatibility with multiple versions of an API/Data Model?

What pitfalls should I watch out for?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

靑春怀旧 2024-08-23 10:30:43

实际上,所有SOLID模式都适用于此,但特别是单一职责原则 (SRP) 和开放/封闭原则 (OCP)。

OCP 特别声明该类型应该对扩展开放,但对修改关闭 - 这听起来很适合您的情况,因为这是确保向后兼容性的一种方法。

SRP 在这里也非常有帮助,因为它意味着如果一个类只做一件事,并且该事情变得过时,它不会带来很多其他问题。只能任其自生自灭。

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

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

Practically all the SOLID patterns apply here, but particularly the Single Responsibility Principle (SRP) and Open/Closed Principle (OCP).

The OCP specifically states that the type should be open for extension, but closed for modification - that sounds like a good fit in your case, because this would be a way to ensure backwards compatibility.

The SRP is also very helpful here because it means that if a class does only one thing, and that thing becomes obsolete, it doesn't drag along a lot of other problems. It can just be left to die on its own.

On a more practical level, I would suggest that you follow two principles:

TDD (or just a comprehensive unit test suite) will help protect you against breaking changes.

染火枫林 2024-08-23 10:30:43

一个可能有用的想法是 Eric Evans 在他的书中讨论的“反腐败层”领域驱动设计 -该模式的关键动机是将您的系统与另一个系统的更改(和特性)隔离开来。

One idea that may be useful is the "anti-corruption layer" discussed by Eric Evans in his book Domain Driven Design - the key motivation for the pattern is to insulate your system from changes (and idiosyncrasies) of another.

離殇 2024-08-23 10:30:43

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

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

但是,如果没有恒定点并且一切都在移动,那么我会放弃这个项目!这是不可能的!

You mentioned that the code is for testing custom hardware. Will your code (i.e. testing routines) also change? Will your code be testing a circle today and a triangle tomorrow or the same basic circle that is evolving day by day?

If there is a constant point around which things move then I would start from there and write wrappers for each version of API and Data Model that would link to the center given the techniques suggested in the other answers.

However, if there is no constant point and everything moves then I would abandon the project! It cannot be done!

樱娆 2024-08-23 10:30:43

您的 API/数据模型是否为您提供元数据?如果是这样,那么最好使用它来使您的代码尽可能独立于 API 更改。例如,如果您有机会使用数据模型模式生成通用的数据模型访问例程,那么您应该这样做。当然,这仅对某些类型的操作有意义。

Does your API / your data model provide you with metadata? If so, it would be a good idea to use this to make your code as independent from API changes as possible. For example, if you have a chance to generate your data model access routines generically by using a data model schema, you should do this. Of course, this makes only sense for certain types of operations.

蓝戈者 2024-08-23 10:30:43

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

Write your own wrapper to interface between your code and the stuff you don't control. Then you can write your code against the API the wrapper exposes, and only have to worry about interop in the wrapper itself.

儭儭莪哋寶赑 2024-08-23 10:30:43

最好的选择是让您公开的 API 要求请求中包含版本号。这样您就可以选择要创建的正确对象。最坏的情况是,每一次改变都会被破坏,最终你会得到几十个类。最好的情况是您的设计可以处理它,并且您只会时不时地得到单独的类。在这方面,继承可能会成为你的朋友。最重要的是,如果您需要与快速变化的 API 保持 100% 向后兼容性,那么您基本上就完蛋了。您要么最终得到一个巨大的难以维护的类,要么得到几个能够正确响应版本控制的类。

Your best bet is to have the API you expose require a version number to come in with the request. That way you can select the correct object to create. Worst case, every change is breaking and you end up with dozens of classes. Best case is that your design can handle it and you only end up with separate classes every now and then. Inheritance is probably going to be your friend on this one. The bottom line is you're basically screwed if you need to maintain 100% bacwards compatibility with a rapidly changing API. You're either going to end up with one gigantic unmaintainable class, or several classes that respond correctly to versioning.

时光无声 2024-08-23 10:30:43

1)大量的单元测试。

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

确保测试是基于功能需求,即不是如何编写函数,而是基于什么为了不破坏其他代码,它必须这样做。

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

2) 要求所有 API 和数据模型有良好的正式规范。这确保了它们的设计会更加仔细,并且不会在未经深思熟虑或毫无理由的情况下随意进行更改。

1) Lots of unit tests.

Whenever you write a piece of code, publish a lot of unit tests for the code that future versions must pass in order to be checked in.

Make sure that the tests are based on functional requirements, i.e. not how the function is written, but what it must do in order not to break other code.

This will help people from checking in changes that break other code.

2) Require good formal specification of all API's and data models. This ensures that they will be designed more carefully, and that changes won't be thrown in nilly-willy without thought or reason.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文