Seven Deadly Sins of a Software Project

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

可维护性是现代软件开发最有价值的优点。Maintainability(可维护性)基本上可以衡量为新开发人员在开始进行重大更改之前学习软件所需的工作时间。时间越长,可维护性越低。在某些项目中,这个时间要求几乎无限,这意味着它实际上是不可维护的。我相信有七个基本和致命的罪恶使我们的软件不可维护。以下是它们。

Anti-Patterns

很遗憾,我们正在使用的编程语言过于“灵活”。它们允许太多,禁止太少。例如,Java并不禁止你将整个应用程序放在一个名为“类”的单一实体中,其中包含数千个方法。从技术上讲,这个应用程序可以编译并运行。但这是一个众所周知的反模式,被称为上帝对象

因此,反模式是一种在技术上可接受的设计方式,但普遍认为是错误的。每种语言都存在许多反模式。它们在产品中的存在就像是活体器官中的肿瘤一样。一旦开始生长,很难停止。最终,整个身体都会死亡。最终,整个软件变得难以维护,必须重新编写。

一旦你容忍了一些反模式,你最终会得到更多的反模式,而且这个“肿瘤”只会越来越大。

这在面向对象语言(Java、C++、Ruby和Python)中尤其如此,主要是因为它们继承了很多来自过程性语言(C、Fortran和COBOL)的特性。而且,面向对象编程的开发者往往倾向于以过程性和命令式的方式思考。不幸的是。

顺便说一下,除了现有的众所周知的反模式列表,我还认为以下几点是相当糟糕的编码方法。

我在这里唯一的实际建议是阅读和学习。也许这些书能对你有所帮助,或者我的书 “优雅的对象“。始终对你的软件质量持怀疑态度,不要在它“仅仅工作”时放松警惕。就像对待癌症一样,越早发现,生存的机会就越大。

Untraceable Changes

当我查看提交历史时,我应该能够知道每个更改了什么,谁进行了更改,以及更改的原因。此外,获取这三个答案所需的时间必须以秒为单位进行测量。在大多数项目中,情况并非如此。以下是一些建议:

始终使用票据。无论项目或团队大小如何,即使只有你一个人,为解决的每个问题创建票据(GitHub问题)。在票据中简要解释问题,并在那里记录你的思考。将票据用作与问题相关的所有信息的临时存储。将可能在未来有任何意义的所有内容发布在那里,以便其他人在尝试理解那些“几个奇怪的提交”时能够理解。

在提交中引用票据。不用说,每个提交都必须有一条消息。没有消息的提交是一种非常糟糕的做法,我甚至不想讨论为什么。但仅有一条消息还不够。每条消息必须以你正在处理的票据号开头。GitHub(我相信你正在使用它)将自动链接提交和票据,增加了更好的追溯性。

不要删除任何内容。Git允许我们进行“强制”推送,覆盖先前存在于服务器上的整个分支。这只是一个例子,说明你可以销毁开发历史。我也曾经多次看到人们在GitHub讨论中删除他们的评论,以使工单看起来更“清洁”。这是错误的。永远不要删除任何东西;让你的历史与你同在,无论它现在看起来多么糟糕(或混乱)。

Ad Hoc Releases

每个软件在交付给最终用户之前都必须进行打包。如果是Java库,它必须被打包成一个 .jar 文件并发布到某个存储库;如果是Web应用程序,它必须部署到某个平台,等等。无论产品的规模大小如何,总会有一个标准的流程来进行测试、打包和部署。

一个理想的解决方案是自动化这个过程,以便可以通过一个命令从命令行执行它:

$ ./release.sh
...
DONE (took 98.7s)

大多数项目都远未达到这一点。它们的发布过程总是涉及某种魔术,由负责此过程的人(也被称为DevOp)在各处点击某些按钮,登录某个地方,检查某些指标等等。这样的即兴发布过程仍然是整个软件工程行业的一个典型问题。

我只能给出一个实际的建议:自动化。我使用rultor.com进行自动化操作,但你可以使用任何你喜欢的工具。重要的是整个过程完全自动化,并且可以从命令行执行。

Volunteer Static Analysis

静态分析 让我们的代码看起来更好。通过使其看起来更好,我们不可避免地使其更好地工作。但这仅在整个团队被(强制性地)迫使遵循静态分析器规则时才会发生。我在《严格控制Java代码质量》中已经写过这方面的内容。在Java项目中,我使用qulice.com,而在Ruby中使用rubocop,但几乎每种语言都有许多类似的工具。

你可以使用其中任何一种,但请务必强制使用!在大多数使用静态分析的项目中,开发人员只是构建出漂亮的报告,然后继续以他们之前的方式编写代码。这种“自愿”方式对项目没有任何好处。而且,它会产生一种质量的错觉。

我想说的是,在您的部署流程中,静态分析必须是强制性的一步。如果违反了任何静态分析规则,构建将无法通过。

Unknown Test Coverage

简而言之,测试覆盖率是指软件在单元测试或集成测试中被测试的程度。覆盖率越高,在测试运行期间执行的代码”量”越大。显然,更高的覆盖率是一件好事。

然而,许多项目开发者根本不知道他们的覆盖率。他们只是不测量这个指标。他们可能有一些测试,但没有人知道它们对软件的深入程度以及哪些部分根本没有经过测试。这种情况比被测量并向所有人报告的低测试覆盖率要糟糕得多。

高覆盖率并不保证高质量。这是显而易见的。但未知覆盖率是可维护性问题的明显指标。当新的开发人员加入项目时,他或她应该能够进行一些更改并查看这些更改对覆盖率的影响。理想情况下,测试覆盖率应该像静态分析一样进行检查,并且如果低于某个预定义的阈值(通常在80%左右),构建应该失败。

Nonstop Development

我所指的”nonstop”是指没有里程碑和发布版本。无论你正在编写什么类型的软件,你都必须经常发布和进行版本化。一个没有明确发布历史的项目会变得难以维护。

这主要是因为可维护性完全取决于我能否通过阅读你的代码来理解你。

当我查看源代码及其提交和发布历史时,我必须能够知道其作者的意图,项目一年前的进展情况,现在的发展方向,以及其路线图等等。所有这些信息必须在源代码中,并且更重要的是在Git历史中。

Git 标签和 GitHub 发布说明 是两个强大的工具,它们为我提供了这些信息。充分利用它们。此外,不要忘记产品的每个二进制版本都必须立即提供下载。即使项目目前正在进行 3.4 版本的开发,我也必须能够下载版本 0.1.3 并立即进行测试。

Undocumented Interfaces

每个软件都有其应该使用的接口。如果它是一个Ruby gem,那么我将作为最终用户使用它的类和方法。如果它是一个Web应用程序,那么最终用户将看到并控制以使用该应用程序的Web页面。每个软件项目都有接口,并且必须进行仔细的文档记录。

就像上面的一切一样,这也是关于可维护性的。作为一个项目中的新程序员,我将从其接口开始学习。我应该能够理解它的功能并尝试自己使用它。

我在这里谈论的是用户文档,而不是开发者文档。总的来说,我反对将文档放在软件内部。在这里我完全同意《敏捷宣言》(Agile Manifesto)的观点——可工作的软件比全面的文档更重要。但这并不是指“外部”文档,它是供用户阅读的,而不是开发者。

因此,必须清楚记录用户与软件的互动。

如果您的软件是一个库,那么它的最终用户是软件开发人员,他们将使用它—不是为之做出贡献,而只是将其作为一个”黑盒子”来使用。


These are the criteria being used to evaluate the open source projects entered in our award competition.

Translated by ChatGPT gpt-3.5-turbo/35 on 2023-09-20 at 20:59

sixnines availability badge   GitHub stars