开发指南

Orekit开发遵循以下准则。

开发

Orekit是一个低级别的库。它可以在无法预见的非常不同的上下文中使用,从快速研究到关键操作。主要的驱动目标如下:

  • 验证

  • 健壮性

  • 可维护性

  • 效率

第一个目标,验证,意味着测试必须尽可能广泛。它们应该包括现实的操作案例,也应该包括意外情况。必须使用jacoco工具来监控测试覆盖率。我们希望达到非常高的覆盖率水平。我们没有设定强制性的目标数值,只是在这里提供一些指导方针。然而,60%的行覆盖率显然是完全不可接受的,80%将被认为是欺骗性的。

第二个目标,健壮性,对于像Orekit这样的低级组件有一些特定的影响。在某种意义上,它可以被认为是前一个目标的延伸,因为它也可以通过测试来改进。它也可以通过分析源代码或二进制代码的自动检查工具来改进。已经配置了spotbugs工具,用于使用maven插件自动检查库。

然而,这还不够。库的目的是供库开发团队不知道的应用程序使用。库的开发应该尽可能灵活,以便与具有特定约束的环境合并。例如,也许一个应用程序应该在数月或数年内全天候运行,因此缓存所有结果以提高效率可能在这种用例中是灾难性的,或者它应该嵌入到服务器应用程序中,因此绝不能打印到标准输出。经验表明,开发库比开发高级应用程序更困难,因为大多数约束在之前是已知的。

第三个目标,可维护性,意味着代码必须可读、清晰和有良好的文档。这个目标的一部分是通过下一节中解释的风格规则来强制执行的,但这只是针对自动和简单的检查。保持一个干净和可扩展的设计是很重要的。实现简单性真的很难,所以这个目标不应该被轻视。好的设计是在两个极端之间的平衡,一个是太少的对象在内部做太多的事情并且彼此忽略,另一个是太多的对象单独无法工作,总是需要一堆其他对象来工作。始终以平衡的方式思考,并检查如果从设计中删除某些内容会发生什么。经常情况下,删除某些内容会改善设计,应该这样做。

第四个目标,效率,应该小心处理,以免与第二和第三个目标(健壮性和可维护性)发生冲突。效率是必要的,但是过于追求效率可能会导致过于复杂、难以维护的代码,过于特定、脆弱的代码,而且不幸的是,往往没有任何收益,因为过早的优化和没有根据的猜测。

一个令人惊讶的技巧,乍一看可能似乎奇怪和不合适,已经在Orekit的许多部分中使用,并应被视为核心指导方针。这个技巧是使用不可变对象。这个技巧提高了效率,因为避免了许多昂贵的复制操作,甚至是为了防御性编程而添加的不必要的复制操作。它提高了可维护性,因为类本身和使用它们的类都要简单得多。它还提高了健壮性,因为许多(真的很多...)难以捕捉的错误是由可变对象引起的,这些对象在一些深埋的代码中被改变,并对忘记执行防御性复制的用户代码产生影响。轨道、日期、向量和旋转都是不可变对象。

源代码控制管理

使用的源代码控制管理系统是Git。主要的Orekit存储库位于https://gitlab.orekit.org/orekit/orekit.git

从版本9.0开始,分支管理工作流程是根据git flowOrfeo ToolBox Workflow进行调整的。

Orekit git工作流程

这意味着开发仅在develop分支上进行。开发人员创建功能分支,并在准备就绪时将其合并到develop分支上。develop分支应始终可用,以便希望使用最新功能的人可以使用它(例如创建每夜构建或准备应用程序以适应即将发布的功能)。

为了提高可追溯性,当将功能分支合并到develop分支时,应使用

git merge --no-ff

使用--no-ff标志可以防止快进,以便历史记录清楚地显示在此时存在一个功能分支。

功能分支是临时的,当它们不再有用时会被删除。功能分支可能仅存在于一个开发人员的工作空间中,从不出现在主存储库中,但是如果开发人员想要共享工作或需要社区反馈,它们也可以推送到主存储库中。

当需要发布版本时,应创建一个专用分支,名称遵循release-x.y的模式。这些分支是从develop分支创建的。当发布准备就绪时,将该分支合并到master分支和develop分支中。一旦设置了发布分支,它将保持不变。这允许依赖于此特定版本的用户能够检索随后发布的修复程序(即x.y.1、x.y.2等)。

在发布并推送到master后,如果在发布版本中发现了严重问题,则可能需要发布紧急bug修复。这些短期的bug修复分支直接从master创建,专门用于此目的。这些bug修复分支将合并回master和develop分支。

master分支始终指向最新的稳定发布版本。不会直接在此分支上进行工作。只有通过将发布分支或bug修复分支合并到master分支上才会更新它。

代码风格规则

为了阅读的便利性和一致性,所有新的开发都应保留现有的代码风格。这些规则是常见的规则,主要继承自Sun Code Conventions for the Java Programming Language指南风格和默认的checkstyle工具配置。以下是其中的一些规则。完整的定义由项目根目录中的checkstyle配置文件给出。

  • 头部规则

    所有源文件都以Apache许可证头部开始,

  • 缩进规则

    不使用制表符,使用4个空格缩进,case语句不缩进,

  • 运算符换行规则

    在运算符之后换行(与Sun不同),

  • 空格规则

    运算符周围有空格,方法参数的开括号之前没有空格,行不以空格结尾,

  • 大括号规则

    开放的大括号在行尾,与相应的关键字(ifforwhilecasedo)的开始对齐,

  • 编码规则

    字符编码为UTF8,在Linux开发机上,git属性core.autocrlf应设置为input,在Windows开发机上应设置为true(以确保在所有操作系统上进行正确的转换),

  • 命名规则

    类名以大写字母开头,实例方法和字段名以小写字母开头,类字段全部大写,单词之间用下划线分隔,

  • 排序规则

    类变量先出现,然后是实例变量,然后是构造函数,最后是方法,public修饰符先出现,然后是protected修饰符,最后是private修饰符,

  • javadoc规则

    所有元素都有完整的javadoc,即使是私有字段和方法(有一些罕见的例外情况,例如从Fortran语言翻译的代码和具有大量参数集的模型),

  • 健壮性规则

    switch/case结构有一个默认参数,即使已经处理了所有可能的情况,尽可能多的类是不可变的,

  • 其他规则

    禁止使用star导入,参数和局部变量尽可能使用final修饰。

设计规则

  • 覆盖率(验证)

    寻求至少80%的行测试覆盖率(覆盖率越高越好)

  • spotbugs(健壮性)

    修复spotbugs发现的所有错误和警告

  • 无运行时假设(健壮性)

    不要对使用Orekit的应用程序的运行时环境做任何假设(它们可能被嵌入在没有控制台、没有可能的用户交互、没有网络、没有可写文件系统、没有可停止的主程序、有内存限制、时间限制、在不同的语言环境中运行...)

  • 简单性(可维护性)

    遵循奥卡姆剃刀原则或其在计算机科学中的变体:KISS(保持简单,愚蠢)

  • 平衡设计(效率)

    追求效率,但不要超越健壮性和可维护性

  • 不可变对象(健壮性,可维护性)

    尽可能使用不可变对象

  • checkstyle(风格)

    修复checkstyle发现的所有错误和警告