注册
登录
新闻动态
其他科技
返回
代码质量:企业、底线和善解人意的程序员所关心的问题
作者:
糖果
发布时间:
2024-04-11 06:36:50 (8天前)
来源:
empathetic-programmers/
代码质量会影响程序员的精神状态、团队内部的沟通以及对工作的激励。改进您的代码,您就可以从整体上改善组织的健康状况和能力。 高质量代码的价值可能难以传达。一些经理将其视为笨蛋,对于过于挑剔的程序员来说是一种昂贵的爱好,因为投资于代码质量会在短期内减慢开发速度,而且似乎不会改变用户体验。但事实并非如此。 确实,对代码质量缺乏组织理解的科技公司可以快速启动并在短期内取得成功。但这样做时,他们会产生一种无形的债务,每次更改代码时都会增加。这笔债务不会长期处于无形状态。一旦产品超过了非常低的复杂性阈值,债务就会到期,逐渐消耗其开发团队的生产力和软件的可用性。当我们谈到“技术债务”时,这些就是我们所谈论的危险。 生产软件的组织处于一千个不同变量的交集处。凡是影响一个程序员的精神状态,他们的团队内部沟通,或连接到其工作的积极性很可能在他们的代码中得到体现。因此,提高代码质量在一定程度上是改善组织健康和整体能力的问题。在本文中,我将简要定义代码质量并解释它如何影响整个公司,然后将一些可有效提高代码质量的组织习惯归零。 ##### 什么是代码质量? 在某种程度上,学习编码就是学习与机器产生共鸣:它对细节的高度关注,需要匹配的括号和一致的大小写,以及它对错误状态的无助。这些需求可能是如此陌生和不透明,以至于我们中最有经验的人仍然要花费数小时甚至数天的时间来寻找相当于源代码几个字符的错误。这是征税。有时,对我们的机器产生共鸣是我们所能处理的。在这些情况下,我们依靠一个简单的指标:它是否能完成工作?由于代码的首要目的是完成一项工作,因此有时我们不会超越这一点。 但是,除了最小的项目之外,这种方法对于任何项目都是不可持续的。代码不是数独,每个问题都有一个正确的解决方案。编写任何计算任务的方法有无数种,有些方法比其他方法更简单、更可预测。随着时间的推移,这里的微小差异会累积起来。代码编写一次,阅读一千次。程序员在修复错误或添加功能时阅读代码。他们阅读代码来记住他们的应用程序是如何工作的。他们阅读代码以发现可以在其他地方重用的模式。唯一比阅读代码更频繁地执行代码的事情就是执行它。这是我们关注代码质量的根本原因。一段代码的有用性与它对阅读它的人的影响有很大关系. 当我们编写好的代码时,我们为他们节省了时间和精力。我们让他们的工作更轻松。我们正在进行一项投资,日复一日、年复一年地支付股息,直到应用程序达到其生命周期的尽头。 因此,具有讽刺意味的是,一旦我们训练了我们的思想对计算机产生共鸣以便我们可以编写工作代码,那么我们就有责任记住如何与人类产生共鸣,这样我们的代码就不会让他们感到沮丧。 从机械角度来看,代码质量是什么样的?多 书 已经 被 写关于这个问题,所以我不会尝试深入讲解。但总的来说,高质量的代码是可以快速理解的代码。如果程序员可以从代码库中随机选择一个方法或类并在几分钟内深入理解它——不仅仅是它的功能和业务逻辑,而是它所依赖的一切以及它可能使用的每一种方式——而无需查阅太多其他文件,那么代码库可能是高质量的。一旦实现了这一点,代码是否能正常工作的问题就不那么重要了;它可以被更改、修复或删除,无需太多风险或努力。 当然,我在这里描述的是一个哲学理想。在现实世界的应用程序中,总会有一些部分不可避免地复杂或令人困惑。但即使是这些作品的质量也有很大差异。没有任何情况下代码质量完全脱离了程序员的掌控。 ###### 影响代码质量的几个最重要的因素是: - 封装。高质量的代码通常由自包含组件组成:不能通过修改自包含组件外部的东西来改变它的行为,组件也不会修改它外部的东西(在合理范围内——它使组件读取和更新数据库的意义,如果这被理解为它的工作)。这节省了开发时间,因为当需要修复、更新或删除组件时,程序员花更少的时间搜索外部原因和影响。 - 惯用代码。现代编程语言具有用于最常见任务的内置语法和方法,例如将字符串转换为数字或确定集合是否包含特定元素。这些比程序员从头开始编写的任何东西都更可靠、更高效、更广为理解,并且比自定义方法需要的代码少得多。以惯用方式编写的代码(即,尽可能多地使用一种语言的约定和内置特性)更具可读性并且需要更少的维护。 - 有意义的名字。代码库中的变量和方法由编写它们的程序员命名。无意义的名称,如 `x` 或 `fn`,要求程序员在阅读使用它们的代码时理解和记住额外的上下文层。如果在一个地方有多个这些,则不可能将所有内容都保存在工作记忆中。高质量的代码使用特定和描述性的变量名称,例如 `departmentName` 或 `getAnnualExpenses`。尽管这里可能过于冗长,但对于第一次阅读代码的程序员来说,与其说太少,不如说一个说得太多的名字。 - 低圈复杂度。任何时候计算机做出决定,就像 if 语句或 for 循环一样,后面的代码会增加一层含义:在一个条件下,代码将被执行或重复;在另一种情况下,它将被跳过。“圈复杂度”是指流程中存在的决策数量的指标。与前一点一样,随着含义层数的积累,程序员的工作记忆可能会成为瓶颈。虽然决策对于应用程序的有用性至关重要,但高质量的代码可以最大限度地减少决策点及其包含的代码,并尽可能避免将它们相互嵌套。 重要的是要注意,虽然代码质量包括一些可以衡量的因素,但代码质量的每一个具体衡量标准都是不完美的,而且很容易被玩弄。没有任何产品或工具可以自动和明确地评估代码库的质量。但是,您可以使用启发式方法来了解代码质量并查看可能存在的问题。 例如,单元测试是测试应用程序行为的代码片段。它们以快速且可重复的方式执行此操作,确保应用程序随着其增长和变化而继续正常工作。与低质量代码相比,单元测试更有可能伴随高质量代码。他们奖励并鼓励质量,因为构成良好代码的东西——封装、松耦合、简洁、简单等——也使测试更容易。这改变了程序员的阻力最小的路径:如果他们正在为以前未测试的代码编写单元测试,有时简化和重新排列该代码比以当前形式测试它更容易。如果程序员知道他们将编写单元测试作为开发过程的标准部分,那么他们首先会被激励编写更好的代码。 ##### 代码质量的影响 软件应用程序的本质是不断增长,不仅在规模上,而且在复杂性上。复杂性有多种形式。其中一些是低质量代码的结果,但其他一些是应用程序功能和价值的基本部分。出于以下几个原因,软件复杂性具有商业价值: 软件过程可以吸收问题空间的复杂性。这种复杂性被转化了,而不是被破坏了。软件永远不会比它实际解决的问题更复杂(尽管构建良好的软件隐藏了这个事实)。 通过增加复杂性(通常在部署阶段),产品可以适应越来越多的用例。这通过根据与特定行业、公司或用户的相关性隐藏或自定义功能来为产品创造更大的市场。 好的软件是按照可访问性、可观察性、弹性和视觉吸引力的高标准构建的。所有这些都需要额外的代码,因此增加了复杂性。 增加价值或增加竞争优势的复杂性是“良好的复杂性”。良好的复杂性是我们构建软件的原因。使代码难以理解、维护和构建的复杂性是“糟糕的复杂性”。糟糕的复杂性是软件产品失败的主要原因。良好的复杂性是软件目的和设计的一部分。糟糕的复杂性是偶然的,当程序员或他们的经理在实现过程中犯错误时就会出现(我将在后面讨论导致这种情况的原因)。 定义代码质量的一种有用方法是不良复杂性与良好复杂性的比率。保持这个比率低有很多好处——我一直把它称为“高质量代码”。 首先,它可以长期保持较低的开发和维护成本。考虑下图: 跟踪两条曲线的图形。 x 轴是时间,y 轴是累积功能。 有一条垂直虚线在 x 轴中偏左代表一个拐点,标记为“这个点发生在几周(而不是几个月)内”。 第一条曲线,棕色,代表内部质量低的软件; 它迅速上升直到拐点,然后几乎趋于平稳。 蓝色的第二条曲线代表内部质量高的软件; 它比另一个低,直到拐点,在那里它迅速超过它。 资料来源:“高质量的软件值得付出代价吗?” 通过马丁福勒 对于任何持续数周以上的项目,开发速度部分取决于代码质量。这是总拥有成本的一个重要因素——换言之,公司的底线直接面临风险。一项研究发现,复杂性占软件维护成本的 25%,占软件生命周期总成本的 17% 以上。Stripe 2018 年的一项民意调查发现,全球每年处理“不良代码”的成本高达 850 亿美元。这些数字仅涉及开发时间和工资方面的成本;运送有缺陷的软件或被竞争对手击败的成本也值得考虑。由于不良代码的影响会持续到它被删除,唯一明智的方法是尽早并经常处理它。 其次,代码质量是程序员工作满意度的一个因素。想要吸引世界一流人才、提高员工敬业度和限制人员流动的公司不能忽视这种关系。营业额尤其是影响软件项目成功或失败的研究因素。这可能是因为程序员在他们不太熟悉的项目上犯了更多的错误。 第三,代码质量驱动产品质量。高质量的代码不太可能有错误,这是用户投诉的主要驱动因素。代码质量还与商业成功和减少安全漏洞相关。代码质量当然不是产品在市场上的性能的唯一因素,也可能不是最重要的因素。但即使是最有能力的组织也很难推销一个漏洞百出或容易受到黑客攻击的产品。 ##### 组织如何提高代码质量 代码质量需要投资。如果没有资源的承诺,它就无法增加——资金、开发时间和最后期限谈判是其中最突出的。它也不能通过使用威胁、惩罚或加班来增加;在导致代码错误的情况下,代码无法改进!好消息是重构——积极提高代码库质量的做法——不需要停止所有其他开发活动。它可以成为开发过程中常规且干扰最小的部分,团队在继续构建和改进功能的同时会参与其中。 以下是一些促进更高质量代码的组织习惯和能力。 ##### 可持续步伐 在最好的情况下,编程是很困难的。如前所述,程序员的编码能力在很大程度上取决于他们的心理状态。快乐、充足的休息和低压力水平都是重要的因素。 确保程序员有足够的脑力资源来做最好的工作的第一个方法是避免加班。程序员代码的质量在标准的八小时工作日结束时会下降,更不用说超过几个小时了。许多程序员在过度疲劳、压力或生病时都有过编码的经历,然后第二天发现他们的所有工作都必须取消或重写。这是“净负工作”,低质量的代码实际上增加了项目剩余的工作量。从长远来看,没有什么可以弥补缺乏休息——咖啡因、微打盹、乒乓球桌和免费啤酒都无法复制一个宁静的夜晚和一夜好眠的好处。 通过坚持不断加班来助长倦怠的公司不仅是滥用职权,而且是弄巧成拙。生产力的任何初始收益都将被劣质产品迅速淹没。另一方面,那些将开发团队安排在一个短期、可持续和灵活的工作日内,允许有充足的休假和病假的公司,可以期待长期稳定和高质量的产出。 在其他有能力的组织中加班的一个常见原因是期限压力。截止日期通常基于财务动机或日程安排问题,而不是软件开发的现实。程序员不能通过更努力地思考或更快地打字来加速项目。当最后期限临近时,他们通常会采取唯一可用的捷径,那就是降低质量。这可以通过围绕最后期限仔细规划和制定策略来避免。 第一部分是估计。软件估算是一项复杂的技能,需要专门的培训。大多数程序员和经理都没有接受过这种培训。在缺乏估算技能的情况下,团队有可能退回过于简单的公式,例如“猜猜需要多长时间,然后将猜测加倍,然后再加倍”。这里最好的情况是项目提前完成,项目经理只能用即兴的方法来填补剩余的开发时间。但最糟糕的情况是项目交付延迟或几乎无法运行。因此,如果一个组织缺乏时间或意愿来培养软件评估技能,与其最终让客户失望,不如为极其慷慨的截止日期进行谈判。 期限管理的第二部分是优先级。优先级不仅仅是关于先构建哪些东西;它是关于构建哪些东西的。每个开发路线图都可能包含被高估(难以构建且对用户没有特别价值)或被低估(易于构建且对用户非常有价值)的功能。一个有效的经理会将他们的团队的努力集中在频谱的后期,尤其是在最后期限临近的时候。 如果最后期限管理得当,它们可以成为实现团队软件交付目标的有效激励因素,同时也为正确构建事情留出足够的时间。软件质量与其他任何事情一样,需要专门的时间。 重构作为开发周期的一部分 技术债务就像杂草一样,无论我们采取什么措施来防止它都会冒出来。虽然一些开发实践可以大大减少它,但如果没有事后的好处,就没有办法消除它。将其保持在最低限度意味着定期花时间查找、讨论和修复它。 许多组织使用“20% 规则”作为指导:80% 的开发时间用于功能开发或错误修复,20% 用于重构。这个原则在松散应用时效果最好,因为团队无法准确预测给定任务需要多长时间。并且可能偶尔会出现技术债务成为需要团队全神贯注的障碍的周期,或者当有紧迫的功能发布需要处理而技术债务不得不退居二线时。组织应注意不要陷入其中任何一项工作时间过长的陷阱。 为了获得最佳结果,技术债务任务应该是规划过程的一等公民。也就是说,它们应该与功能、错误和测试任务一起存在于团队的规划软件中(或在他们的白板上,视情况而定)。可以采用 20% 规则,就像“每五个任务中的一个留出进行重构”。这并不一定需要将技术债务任务计划和范围限定到与功能任务相同的详细程度。相反,目标是确保团队的重构工作是可见的,并且他们花在它上面的时间受到保护。 ##### 技术领导和审查 代码质量是许多程序员的第二天性。他们识别低质量代码,了解其影响,并知道如何修复它。对于其他程序员来说,这个概念完全陌生。如果一个项目完全由后者负责,它很快就会陷入缓慢的开发和技术问题。 这两组程序员有什么区别?答案很简单:学习和有意识的练习。不幸的是,无论是大学、训练营还是多年的行业经验都不能用来灌输相关技能——程序员简历上的任何内容都不一定能让他们与众不同。但这不应该让招聘经理夜不能寐。代码质量和重构技能可以在程序员职业生涯的任何阶段学习,并且远没有他们处理的许多其他概念复杂。如果程序员可以访问正确的资源并愿意改进,他们的工作质量可以在几个月内显着提高。 更重要的是,即使他们的程序员的技能参差不齐,软件组织也可以蓬勃发展。如果选择有经验的程序员来领导软件项目的架构、设计和规划,他们对代码质量的理解将成为开发周期 DNA 的一部分。这种技术领先对于高质量的软件是必不可少的。 技能差距也可以通过各种形式的审查来弥补: 设计审查发生在指定任务之后但在编写任何代码之前。分配到该任务的程序员编写一份文件,概述他们的方法:他们计划更新的文件、类和方法;他们将使用的模式和技术;以及他们对设计或业务逻辑可能存在的任何不确定性。然后另一位程序员对该文档提供反馈,其中可能包括纠正误解和建议代码库中已经存在的有用模式或方法。此过程所花费的时间有时很长,但这是一项值得的投资。相对于后来发现和修复它的成本,在开发过程的早期发现缺陷是非常便宜的。 结对编程是指派两名程序员一起实时完成一项任务的做法。一名程序员控制键盘和鼠标,而另一名程序员则给出指示。这允许在开发过程中进行即时审查、反馈和知识转移。研究发现,两个程序员一起工作与单独工作的原始生产力的结果喜忧参半 (尽管它似乎为没有经验的程序员提供了更一致的生产力提升)。然而,当考虑到代码质量时,结对编程几乎被普遍认为是有利的。 代码审查发生在代码编写之后但在作为产品的一部分交付之前。程序员将他们的代码更改提供给团队的其他成员。然后另一个程序员阅读它们并提供反馈,通常建议在代码交付之前应该进行更改。许多代码质量问题只能由人类识别。这是在它们成为产品的一部分之前捕捉它们的最后机会。 如果团队成员经常被要求检查彼此的工作,并且他们之间没有重大的敌对或沟通失败,他们的集体工作的质量将上升到最熟练的程序员的水平。 ##### 代码质量是一种竞争优势 对代码质量的研究并不稀缺(如果上面链接的 25 多项研究还不够,还有更多)。它一次又一次地被证明是影响项目成功或失败、上市时间和产品寿命的一个因素。优先考虑健康代码库的组织正在优先考虑他们的客户、他们的程序员和他们自己的财务可行性。 代码质量也是我们程序员可以送给自己和同事的一份很棒的礼物。如果我们花一些额外的时间来命名变量、重写深层嵌套的逻辑或使函数更具可预测性,那么当我们在项目的整个生命周期中与该代码进行交互时,这些时间将得到多次回报。考虑我们的代码如何影响计算机是最低限度的;思考我们的代码如何影响人类在实践中是一种强大的同理心形式,任何组织都不能忽视。
收藏
举报
1 条回复
动动手指,沙发就是你的了!
登录
后才能参与评论