高质量的软件值得开发吗?


团队通常在实施项目的过程中面临一个问题:应该更注意什么-发布新功能或提高代码质量? 通常,经理选择功能。 通常,开发人员对这种情况感到不满意,他们认为他们没有足够的时间来处理代码的体系结构和质量。

贝特里奇(Betterridge )的法律说:“任何以问号结尾的标题都可以用“否”来回答。 那些认识我的人知道我不同意这种想法。 但是在本文中,我想进一步证明,从本文标题提出问题根本没有道理。 对问题的这种表述表明,在成本和质量之间需要权衡。 而且您必须不断保持平衡。 在本文中,我将证明这种妥协不适用于计算机系统开发领域,实际上,创建高质量的软件最终会更便宜。

尽管本文的主要目标读者是开发人员,但并不需要专门的知识来理解它。 我希望本文能使与开发过程有某种联系的每个人受益,尤其是对那些形成产品开发载体的经理们。

我们习惯在价格和质量之间进行选择。


正如我之前所写的那样,在开发软件时,您经常需要在产品质量和开发成本之间做出选择。 当您购买新的智能手机时,您可以选择。 花更多的钱,获得更快的处理器,更多的内存和改进的屏幕,或者花更少的钱,但牺牲一些功能。 该规则也有例外:有时高质量的产品更便宜。 有时人们甚至无法客观地比较两种产品并选择更好的产品。 例如,他们没有注意到使用完全不同的技术制作的屏幕之间的差异。 但是,“高质量花费更多”这一说法通常是正确的。

软件质量差不多。


谈到软件质量,您应该先定义质量标准。 什么是优质软件? 从现在开始,事情变得有些复杂,因为任何计算机系统都有许多评估质量的标准。 您可以评估UI和UX:用户可以多么快速和简单地解决他的问题? 可以评估可靠性:程序中是否有导致错误和不稳定行为的错误? 另一个标准是体系结构:程序源代码的结构如何,程序员现在可以找到他需要的代码段有多简单和快速?

当然,以上质量标准列表并不完整。 但是这些标准足以说明一件重要的事情。 通常评估最终程序质量的某些标准甚至对最终用户也不可见。 客户可以提供反馈,并告诉该软件如何解决他们的业务问题。 用户可能会抱怨界面不便。 否则他们会抱怨错误,尤其是如果它们导致数据丢失或系统长时间不可用时。 但是用户无法欣赏代码的体系结构和质量。

因此,我将质量标准分为两类: 外部 (例如,UI / UX或存在错误)和内部 (体系结构)。 他们之间最重要的区别是用户可以评估外部质量,但是他们无法理解系统内部架构的好坏。

乍一看,内部质量对用户而言并不重要(仅在最初)


如果用户无法评估软件的内部质量,此标准重要吗? 让我们想象一个假设情况,两个开发团队彼此独立地决定创建一个用于跟踪和预测航班延误的应用程序。 我管理一个团队,丽贝卡领导第二个团队。 这些应用程序的基本功能集大致相同,这两个应用程序的界面也非常方便且经过深思熟虑,这些应用程序中没有严重的错误。 唯一的区别是Rebecca的应用程序的源代码是清晰的结构和组织,而我的团队创建的代码是一堆凌乱的类和方法,名称和名称相互混淆,逻辑上这些代码的互连方式更加模糊。 还有另一个区别:我以6美元的价格出售我的应用程序,丽贝卡以10美元的价格出售几乎相同的应用程序。

由于用户无法访问应用程序的源代码,并且代码的质量不影响用户体验,因此用户为什么要额外支付4美元? 换句话说-为什么要为内部质量多付钱,而这对于用户而言却无关紧要?

如果进一步发展这个想法,您可以得出结论,投资于外部质量比内部质量更有利可图。 在两个应用程序之间进行选择,如果用户具有更好,更方便的界面,则可以选择价格更高的应用程序。 但是用户看不到应用程序的内部结构,更不用说用户可以比较两个应用程序的体系结构。 那么,为什么要为没有带来实际利益的东西付出更多呢? 开发人员为什么要花时间和资源来改善程序的内部质量?

内部质量较高的程序更易于扩展


为什么程序员拥有高质量的代码如此重要? 程序员大部分时间都在阅读和编辑它。 即使在开发新系统时,也几乎总是在已编写代码的上下文中进行工作。 当程序员添加新功能时,他首先需要弄清楚此功能如何适合现有的应用程序体系结构。 然后,通常您需要对体系结构进行更改,以便可以实施新功能。 通常,您需要使用系统中已经存在的数据结构。 因此,您需要了解这些数据结构意味着它们之间存在什么样的关系以及需要添加哪些新的数据结构来实现功能。

高质量的代码使程序员可以快速浏览它。 达到一种很难理解代码的情况实际上非常简单。 逻辑条件可以交织在一起;数据结构之间的关系可以是复杂的和隐式的。 托尼六个月前给变量和函数起的名字可能对他来说是很清楚的,但对于新开发人员来说还是难以理解的,以及促使托尼离开公司的动机。 开发人员通常将其称为“技术债务” (即技术债务 ),换句话说,就是代码当前状态与理想状态之间的差异。

高质量的代码所提供的主要优点之一是,程序员可以快速了解系统的工作方式并进行必要的更改。 将应用程序划分为模块时,程序员无需研究所有500,000行源代码,并且可以快速找到当前所需的数百行。 当程序员为变量,函数和类赋予有意义的名称时,您可以轻松了解每个代码段的功能,而不必深入研究上下文。 如果程序中的数据结构与业务领域中的术语一致,那么程序员很容易将对新功能的请求与系统的工作方式相关联。 技术债务还增加了使用代码的时间。 犯错误的可能性也会增加。 如果由于代码质量差而导致错误,则需要更多时间来定位和修复问题。 而且,如果没有立即发现该错误,那么这将导致生产代码出现问题,并且将来您将不得不花费更多的时间来解决这些问题。

代码中的每个更改都会影响产品的未来。 通常情况下,有一种简单快捷的方法来实现新功能,但要以破坏当前体系结构为代价(即由于技术债务的增加)。 如果程序员选择此路径,则他会更快地发布其功能,但会减慢其他开发人员的工作,这些开发人员以后必须支持此代码。 如果团队中的每个人都这样做,那么即使是一个设计良好,具有良好代码的应用程序,也会迅速陷入技术负担,甚至进行一些更改也将花费数周的时间。

用户希望尽快获得新功能。


我们正在接近一个重要点,即:要回答这个问题,为什么软件的内部质量对于用户仍然很重要? 较高的内部质量可促进新功能的更快发布,因为它们更容易,更快捷且更便宜。 现在,我在Rebecca上的应用程序看起来几乎相同,但是几个月后,Rebecca的高质量代码将使她每周都能发布一个新功能,而我会坚持不懈,尝试解决技术问题并尝试至少发布一个新功能。 我将无法在开发速度上与Rebecca竞争,她的应用程序将很快超过我的功能。 最终,用户将删除我的应用程序并使用Rebecca应用程序,即使它花费更多。


可视化内部质量的影响


程序内部质量高的主要优点是减少了将来更改的成本。 但是编写高质量的代码需要付出更多的努力,这在短期内增加了必要的资源。

下图示意性地显示了如何想象功能的比例以及开发功能所花费的时间。 通常,曲线看起来像这样:


当代码质量不是很高时,这就是开发过程的样子。 起初,开发速度足够快,但随后需要更多的时间来进一步扩展功能。 在某个时间点上,为了进行很小的更改,程序员必须首先学习很多复杂而令人困惑的代码。 进行更改后,发现某些东西已损坏,这导致在测试和修复错误上花费了更多时间。

较高的内部质量有助于后期开发效率。 一些团队甚至设法获得相反的效果,因为每个新功能的发布速度都比前一个新功能快,这是因为可以重用已经编写的代码。 但是这种情况很少发生,因为它需要一支高度专业的团队和良好的工作组织。 但是有时这仍然会发生。


但是,有一个窍门。 在开发的初始阶段,忽略代码质量比遵循高标准更为有效。 但是这个时期什么时候结束?

要回答这个问题,您首先需要弄清楚图像代表伪图形 。 没有一种评估团队绩效的真正方法。 不容易理解不良代码如何影响产品的最终质量(如果存在这种相关性,则说明其相关性如何)。 顺便说一句,这个问题不仅与IT行业有关。 例如,如何评估律师或医生的工作质量?

但是回到问题,在什么时候值得考虑代码的质量。 经验丰富的开发人员认为,不良的代码质量会在项目开始后的几周内开始放缓。 在项目的早期阶段,可以忽略体系结构和代码的优美之处。

同样,根据我自己的经验,我可以说,即使是小型项目,如果在他们的工作中使用现代有效的开发实践并考虑代码的质量,它们也会获得严重的竞争优势。

即使是最好的团队有时也会写不好的代码


那些对开发过程不熟悉的人认为错误的代码表明团队工作不正常。 但是,正如实践所示,即使是最有经验的团队有时也会犯错误并编写错误的代码。

为了清楚地说明这一点,我想向您介绍与我们最好的团队负责人之一的对话。 那时,他刚刚完成了每个人都认为非常成功的项目。 无论是新功能还是开发所花费的资源,客户都对新系统感到满意。 团队也对完成的项目感到满意。 团队的技术负责人也对结果感到非常满意,但是他承认实际上系统架构并不是那么成功。 我问他:“但是您是我们最好的建筑师之一吗?” 他的回答就像任何经验丰富的建筑师都会回答的那样:“我们做出了明智的决定,但是直到现在,我们才知道如何正确地做。”

许多人将复杂系统的创建与摩天大楼的设计进行了比较。 显然,这就是为什么经验丰富的开发人员被称为“建筑师”的原因。 但是在创建软件的过程中,总是存在一些不确定性,这与其他活动领域的特征不同,而不确定性要小得多。 典型的客户对他们想要的程序了解不多,仅在工作过程中才开始理解。 多数时候,在显示程序的第一个版本的那一刻。 创建程序的要素(编程语言,库,平台)每隔几年就会更改一次。 与摩天大楼的建造类比,您能想象这样一种情况吗,尽管事实上已经建造了一半建筑物,但客户仍要求建筑师增加十几个楼层并更改较低楼层的布局? 事实证明,每两年更新一次用于混凝土生产的技术,其物理性质和特性的情况就变得更加复杂。

面对不断的新挑战,数量和复杂性的增长,团队必须不断提出新的想法。 我们必须越来越多地解决以前没有人解决过的问题,因此也没有针对这些问题的众所周知且经过验证的解决方案。 通常,只有在解决问题时才对问题有清楚的了解,所以我经常听到这样的观点,即至少在工作开始一年后才了解复杂系统的体系结构。 甚至全球最专业的开发团队也无法使系统完美。

一个专业而有组织的团队与组织较松散的团队的区别在于,在系统工作过程中,它减少了技术债务,并且摆脱了现有的债务。 这有助于项目快速发展并尽快发布新功能。 这样的团队会投资创建自动测试,这有助于更快地发现问题,并花费更少的时间查找和修复错误。 这样一个团队的成员一直在努力维护高质量的代码,并迅速消除不良代码,直到它开始干扰前进。 CI系统也为此做出了贡献,特别是在许多人同时从事不同任务的情况下。 作为一个比喻,您可以在煮饭后带进厨房。 不弄脏桌子,碗碟和其他厨房用具是不可能做饭的。 如果不立即清洁它们,灰尘将干dirt,然后将很难清洗。 下次您要煮东西时,这样做会更加困难,因为首先您必须洗碗碟。

DevOps研究与评估(DORA)


乍一看,成本和质量之间的权衡并不是唯一看起来很简单的软件开发领域,但实际上,一切都变得更加复杂。 关于最佳选择是什么,也有广泛的讨论-快速的开发和发布速度,或者较慢的速度和严格的测试。 相信使用第二种方法可以实现生产系统更高的稳定性。 但是, DORA的研究证明事实并非如此。

在收集了数年的统计数据之后,研究人员确定了哪些做法有助于提高团队绩效。 事实证明,最有效的团队一天要多次更新生产服务器,并且从编写代码到发布的代码发布都不会超过一个小时。 使用此方法,您可以释放小零件中的变化,并减少了严重损坏的可能性。 据统计,减少发布频率的团队面临许多严重问题。 此外,习惯了高速度的团队在撞车后可以更快地恢复。 研究还表明,在这样的团队中,流程通常可以更好地保持一致,并且以更有组织的方式运作。

对具有良好架构的系统的支持更便宜


以上我们所讨论的最重要的观点是:

  • 缺乏对代码质量的关注导致技术债务的积累
  • 技术债务减缓了系统开发
  • 甚至专业团队有时也会做出错误的决定。 但是,现代实践的应用和技术债务的定期“还款”使您可以控制债务
  • 保持高水平的代码质量可最大程度地减少技术负担。 这样就可以专注于新功能并以更少的精力,更快,更便宜的方式发布它们。


不幸的是,开发人员通常很难向管理层解释这一点。 我经常听到抱怨,该手册无法通过限制分配给工作的时间来维护高质量的代码。 在回答管理问题时,为什么要在代码的美感上花费额外的资源,开发人员通常会回答这是高度专业化的指标。 但是仅使用此论点就意味着要花费额外的资源来维持高质量,这些资源可以用于其他任务。 这破坏了对专业精神的争论。 事实是,由于劣质的架构和劣质的代码,每个人的生活变得更加困难:开发人员使用它变得更加困难,而客户则花费了更多。 在与管理层讨论代码质量时,我敦促仅将其视为经济指标。 如果内部程序的质量很高,则向其添加新功能将变得更加容易和便宜。 这意味着投资于编写质量代码最终会降低总体开发成本。

这就是为什么文章标题中的问题根本没有道理的真正原因。 从经济的角度来看,将额外的资源花费在体系结构和好的代码上,最终会更有利可图。我们在日常生活中经常遇到的价格与质量之间的权衡不能直接应用于软件的内部质量,而可以应用于外部质量。例如,如果它是一个用户界面。由于在这种情况下,价值与内在质量之间的相关性是非典型的和违反直觉的,因此通常很难实现(甚至向其他人解释)。尽管如此,实现这一点很重要,以便使开发过程尽可能高效。



马丁·福勒(Martin Fowler)还有一篇关于技术债务的文章小预告片:
, , . – . . , . .

Source: https://habr.com/ru/post/zh-CN455938/


All Articles