中断性变更

MRTK 的使用者依赖于具有稳定的版本到发布的 API 图面,因此,它们可以对 MRTK 进行更新,而无需每次进行大量的重大更改。

本页介绍了有关 MRTK 中的重大更改的当前策略,以及围绕如何更好地管理重大更改与对代码进行正确的长期技术更改之间的一些更长期的目标。

什么是重大更改?

如果更改满足列表 a中的任何条件并满足列表 B中的所有条件,则更改是一项重大更改

列出 A

  • 添加、删除或更新任何接口的任何成员或函数 (或删除/重命名整个接口) 。
  • 删除、更新 (更改类型/定义,使任何受保护的或公共成员或类函数的私有或内部) 。 ) 的整个类 (或删除/重命名。
  • 类激发的事件顺序的变化。
  • 重命名无相应 FormerlySerializedAs 标记) 或 ScriptableObject 上的公共属性的任何专用 SerializedField ( (特别是对配置文件) 的更改。
  • 更改 ScriptableObject 上字段的类型 (对配置文件) 的更改尤其如此。
  • 对任何类或接口的命名空间或 asmdefs 的更新。
  • 删除 prefab 的顶层对象上的任何 prefab 或删除脚本。

列表 B

  • 相关资产位于基础包中 (也就是说,它位于以下文件夹之一) :

    • MRTK/Core
    • MRTK/提供程序/
    • MRTK/Services/
    • MRTK/SDK/
    • MRTK/Extensions
  • 相关资产不属于实验命名空间。

重要

位于示例包中的任何资产 ((即 MRTK/示例/文件夹) 的一部分)随时可以更改,因为使用者可以将其作为 "引用实现" 进行复制和查看,但不是 Api 和资产的核心集的一部分。 实验命名空间中的资产 (或更常见,标记为实验性) 的功能是在完成所有截止工作之前发布的功能 (例如,测试、UX 迭代、文档) 并及早发布,以便更快地获取反馈。 不过,由于它们没有测试和文档,而且可能尚未明确所有交互和设计,因此,我们会将其发布到公共应假设它们可以和将更改 (即修改、完全删除等) 的状态。

有关详细信息,请参阅 实验性功能

因为重大更改的外围应用非常大,所以请务必注意,具有显示 "无重大更改" 的绝对规则可能是不可能的,这可能是由于发生重大更改而只能通过合理方式解决的问题。 作为另一种方法,我们真正可以说,"无重大更改" 是指根本不进行任何更改。

我们的主要策略是避免在可能的情况下进行重大更改,并且仅在更改会使重要的客户或框架长期价值时才会发生这种情况。

如何应对重大更改

如果可以在没有重大更改的情况下完成某个操作,并且不会影响长期的结构和生存能力,请不要执行重大更改。 如果没有其他方法,则当前策略是评估每个重大更改,以了解取得更改的好处是否超出了使用者吸收更改的成本。 探讨需要做什么,通常不会发生 PR 或问题讨论本身。

此处可能发生的情况分为几个 bucket:

重大更改增加了值,但可以用不间断的方式编写

例如, 此 PR 添加了一项新功能,该功能最初是用一种被破坏的方式编写的,它修改了现有的接口,但随后又将该功能作为自己的接口被分解。 这通常是可能的最佳结果。 如果执行此操作会危及功能的长期可用性或结构,则不要尝试更改为非中断形式。

重大更改为客户增加了足够的价值

记录重大更改的内容,并提供最佳的缓解措施 (即,如何迁移或更好的工具将自动为客户) 进行迁移。 每个版本可能会包含少量重大更改,这些更改应始终记录在文档中,就像 此 PR中所做的那样。 如果已经有一个1.x: +1 + 1 迁移指南,请向该文档添加说明或工具。如果它不存在,请创建它。

重大更改增加了价值,但客户的痛苦会太高

并非所有类型的重大更改都是相同的,它们都是根据我们的经验和客户体验,更令人头疼。 例如,对接口所做的更改可能会令人头痛,但如果重大更改是客户不太可能在过去 (诊断可视化系统(如) )的情况下进行扩展 但是,如果更改是 ScriptableObject 上某个字段的类型 (例如,在) MRTK 的一个核心配置文件上,这可能会导致巨大的客户难题。 客户已经克隆了默认配置文件,合并/更新配置文件可能非常难以手动执行 (即,在合并期间通过文本编辑器) ,并重新复制默认配置文件并重新配置所有内容,这极有可能导致难以调试回归。

必须将这些更改放回到托架上,直到存在一个分支存在,这将导致重大更改 (以及将为客户提供升级) 的重要价值。 此类分支当前不存在。 在我们未来的迭代规划会议中,我们将回顾一组 "过于严重" 的更改/问题,以确定我们是否达到了一项关键的质量,以便能够合理地执行一组更改。 请注意,由于我们拥有的工程资源有限,因此,启动 "一切都是允许的" 分支,而不是由于有限的工程资源而进行 此类分支存在时,需要有一个明确的用途和良好的通信开始和结束日期。

重大更改的长期管理

从长远来看,我们应该设法通过增加 列表 B中的条件集来减少重大更改的范围。今后,在 列表 A 中进行一组任务,对于我们认为位于 "公共 API 图面" 的一组文件和资产,将始终中断。 我们可以更自由地利用迭代 (例如,通过更改内部实现详细信息,以便更轻松地在多个类之间重构和共享代码,如) 更明确地说明代码的哪些部分是官方面,而不是实现详细信息。

我们所做的一件事就是介绍了 "实验性" 功能 (的概念,该功能在实验命名空间中存在,它可能没有测试/文档,而且可能会被删除并更新,而不) 警告。 这样,就可以自由地添加新功能来更早地添加新功能,但不能立即将其绑定到 API surface (,因为我们可能未) 充分考虑 API 图面。

将来可能会有所帮助的其他一些示例

  • 内部关键字的用法。 这样,我们就可以在自己的程序集中使用共享代码 (用于减少代码重复) 而无需向外部使用方公开任何东西。
  • 创建 "内部" 命名空间 (例如 MixedReality。Toolkit。内部实用程序) ,我们在其中公开了该内部命名空间中包含的所有内容,随时都可以更改和删除,等等。这类似于 c + + 标头库如何使用::内部命名空间来隐藏其实现细节。