在Joel Spolsky的博客文章“The Joel Test:12 Steps to BetterCode”中,他描述了一个由12个简单的是非问题组成的测试。如果回答“是”,你就得一分。10分可以接受,12分很完美。如果你的分数低于10分,你的软件迟早会遇到麻烦。
虽然Joel‘s Test仍然是良好的软件开发和工程的优秀指标,但20年过去了,许多改变游戏规则的技术已经出现,比如移动应用程序、公共云和整体上更好的工具。Git和GitHub的成功改变了我们开发软件的方式。在本文中,我想用当代问题来扩展Joel的测试:
扩展测试包括24个是非题。就像乔尔的测验一样,如果回答“是”,你会得一分。排名是:
此外,我想强调的是,可持续性是我测试的主要目的。许多问题直接或间接地对可持续和健康的代码库做出了贡献,而代码库对于一个成功的长期软件项目乃至一个成功的软件公司来说都是至关重要的。泰特斯·温特斯将可持续代码库定义为:
当您能够更改您应该更改的所有事情时,您的组织的代码库是可持续的,并且在代码库的生命周期中是安全的,并且可以这样做。
一致性是代码库最重要的属性之一,它增强了代码的可读性和可维护性,而这对于可持续的代码来说是必不可少的。一致的代码库更容易掌握,让新开发人员入职更快。新程序员受流行风格的指导,能很快适应它。一致性也是程序员纪律的一个指标,显然您不希望在代码库中有死代码、未使用的导入、错误的缩进和其他错综复杂的内容。所需的一致性可以通过代码样式指南来实现。
充其量,您可以通过使用静态代码分析器、linters和自动格式化工具等工具来执行样式指南的规则。通常,这些工具被集成到构建中,或者在提交之前执行。此外,还有像codereviews这样的手动措施来强制执行公共代码样式。
一致的代码风格可以提高工作效率,例如,Linters可以防止草率的编程错误,自动格式化程序不会给关于缩进和格式化规则的无用(有时是宗教的)讨论留出任何空间。所有代码看起来都是一样的。开发商的品味和自负退居次要地位。
编写自动化测试是可持续代码库的一个主要特征。有很多种测试,但最好的分类来自测试金字塔。
特别是,单元测试构建了基础,并给了开发人员快速行动而不破坏现有功能的信心。单元测试是快速反馈循环的主要支柱。这让开发人员感到满意,质量也很高。一般来说,测试起到了安全网的作用,防止引入新的错误和再次出现旧的错误。
如果没有自动测试,您的代码库将受到侵蚀,只有长期开发人员才有能力进行更改。让新的开发人员上岗将需要几个月的时间,否则永远不会成功。随着时间的推移,显影速度会减慢并最终完全停止。在发布之前严重依赖手动测试是遗漏自动测试的明显标志,并将发布周期延长数天或数周。高性能人员每天进行部署,这在手动测试阶段是不可能的。因此,人工测试应该减少到最低限度或完全避免。
在谷歌,他们实行碧昂斯规则“如果你喜欢,你应该对它进行测试!”";这个规则颠倒了责任,例如,如果有人破坏了一项功能,但没有测试,被破坏的功能的原创者“应该对它进行测试!”
代码评审是软件工程过程中的关键步骤。它们不仅可以防止将错误输入到您的主线中,而且还是知识传递、学习和指导的主要工具。代码评审过程促进了评审者和作者之间的共同理解,并提供了一个讨论权衡和设计决策的平台。审查不仅集中在正确性上,而且还集中在可读性、性能和其他非功能性属性上。
所有这些都将带来更好的解决方案。此外,评审员还练习他们的代码阅读技能,这与代码编写同样重要。除了编译、编译和运行测试之外,代码评审是开发人员反馈循环中的重要一步。在没有经过适当的代码审查的情况下,永远不应该将代码放入主线。
因为代码审查可能会引发激烈的讨论,所以审查人员应该遵守一些代码审查指南,以保证完美的体验。
文档从代码开始。拉取请求的代码注释或良好描述就是很好的例子。因此,好的文档侧重于为什么要做某事。广泛的自述文件.md作为项目的“首页”,应该包含开发人员设置本地开发环境的目的和说明,例如安装先决条件、构建项目、运行测试。
所有这些文档都应由开发人员、操作员或其他技术人员撰写。活的、最新的文档使项目更容易理解,长期的项目成员能够回答为什么要做过去的事情-在大多数项目中,最好的答案是“这是历史上成长起来的”。获得真正洞察力的唯一方法是进行耗费时间的面对面采访。文档有助于保持对不断增长的项目的概述,便于新开发人员开始,并构建可搜索的知识库。过去的决定应该通过良好的文档来阐明,而不是隐藏在人们的标题中。
健康的代码库是开发人员快乐的主要标准。如果你的开发人员在一个糟糕的代码库上工作,他们要么适应糟糕的质量,要么离开。现有的代码库充当了一个榜样。为了获得高质量的代码,持续关注代码健康是很重要的。最好的程序员会被糟糕的代码拒之门外,被健康的代码所拖累。但是什么是健康的代码库呢?
您可以在Google关于CodeHealth的测试博客中找到关于代码健康的更详尽的解释。
不要因为时间或释放压力而用肮脏的代码或变通方法来换取代码的健康。从长远来看,你的结局会非常糟糕。更糟糕的是,您陷入了恶性循环,因为糟糕的代码会减慢您的速度,并且为了满足下一个版本的要求,您添加了更多肮脏的变通方法。因此,始终优先考虑代码健康,即使乍看起来有违直觉。
如今,持续集成有望成为家常便饭。充其量,您可以使用基于主干的开发,并且您的主线始终是可发布的,最好使用特性切换。当务之急是保持主线的绿色,损坏的建筑应该立即修复。小而频繁的发布可以防止仅间歇性地进行大发布时出现的错误甚至停机。
CI有助于避免单调乏味的合并冲突解决方案,因为您的开发人员定期致力于主线。此外,您将在实现阶段结束时消除耗时的集成问题。
“敏捷”的主要目标是尽早识别风险,而不是把它们推迟到项目结束。CI完全支持这一点。使用CI,您将发现集成、设计问题。这使您可以在途中进行航向修正。
指导是培训新员工的一种很好的方式。通过指导计划,您不仅可以在整个组织范围内用软件方法、代码风格指南、代码审查、测试文化和其他策略等最佳通用实践培养一致的工程文化,而且这也是将新员工塑造成高效团队的必备条件。
接受指导的开发人员更有可能留下来。他们感到被认可并被视为一流的员工,因为你从一开始就在他们身上投入了时间和精力。这是给伟大而忠诚的工程师加薪的绝佳方式。
如今,AWS和Azure等公共云提供商提供API来创建、更新和管理您的基础设施。随着API的使用,将整个基础设施存储为代码(IAC)是很自然的。
因为我们谈论的是代码,所以前面的所有要点也适用于基础设施。您应该将其置于版本控制之下,进行代码审查,在您的CI管道中运行测试,并通过格式化和linting工具保持您的代码库的整洁。已知的基础设施工具有库伯内斯清单、头盔图、Terraform或AWSCoudformation.。
如果你的基础结构是可重现的,一个很好的指标是你如何对待你的服务器,就像对待牛或宠物一样?重建故障服务器应该比用胶带粘住故障服务器容易。当心雪花天气!
我的成功在很大程度上是因为找到了这些“真正有天赋”的人,而不是满足于“B”和“C”的球员,而是真正地选择了“A”的球员。…。我发现,当你把足够多的“A”球员聚集在一起,当你完成令人难以置信的工作,找到这些“A”球员中的5名时,他们真的很喜欢相互合作,因为他们以前从来没有机会这样做过。而且,他们不想与“B”和“C”玩家合作,所以这就变成了自我监管,他们只想雇佣更多的“A”玩家,所以你积累了这些“A”玩家的口袋,这就传播了…“。
雇佣优秀的工程师很重要,但留住他们也很重要!最好的工程团队有着共同的心态。工程师们希望与其他有着相同兴趣和目标的工程师一起工作。这创造了一个良性循环,工程师们相互激励,以达到最好的结果。不过要小心,一名新员工可能会扰乱一支A球员团队的平衡。这就是为什么招聘过程非常重要的原因。
你应该把你的工程师当作一流的员工对待。公司认识到自己的价值,会提供专门针对技术的职业,薪酬与高级管理人员的薪酬水平相当。
此外,工程经理在让您的工程师(高兴)方面扮演着至关重要的角色。他们应该知道如何编写代码,并分享相同的工程思维。如果你的工程经理不具备技术技能,你的工程师就不会认真对待他们。更糟糕的是,他们会在某个时候离开,因为他们觉得被误解了。
这一点扩展了乔尔最初的第九点“你用钱能买到的最好的工具吗?”Joel主要关注在您的本地机器上运行的软件工具,如IDE、编辑器、编译器、调试器和类似于第二个监视器的本地硬件。所有这些都使您的程序员既时髦又高效。虽然这仍然是正确的,但如今要让您的开发人员满意,需要的不仅仅是本地工具。
像Amazon AWS或Microsoft Azure这样的公共云是生产力的主要支柱。公共云为您的工程师提供出色的工作体验。自助方式尤为重要,工程师可以通过API和脚本实现应用程序堆栈的自动化,使用最新技术,无需开具工单和获得上级批准即可操作完整的系统。它使您的开发人员能够负责应用程序的整个生命周期,从设计、实现、发布到操作。这是一个很好的生产力助推器。如果您由于法律或其他限制而无法使用公共云,请当心本地企业云。企业非云是一个危险的东西,它提供现代软件堆栈,如Kubernetes或Prometheus,但无法提供公共云的主要优势,如具有API的真正自助服务、灵活性、可伸缩性和按使用付费的价格模式。
其他类型的工具也同样重要,例如支持在一个文档中与多个用户并行协作的Google Docs或Office 365等现代协作工具、Slake等现代通信工具以及GitHub等集成了代码视图、CI管道和公共云的现代版本控制平台。
衡量你的工程部门是否一流的最好方法是“加速”(Accelerate)一书中定义的四个关键指标。
上面的一些指标似乎相互矛盾,比如高部署频率和低更改失败率。但根据DevOpsReport的研究,最好的公司在所有关键指标上都表现出色。
如果你在寻找改进,关键是要永久关注这四个关键点。不要成为昂贵的敏捷转型方法的牺牲品,比如SAFE或其他IT顾问。通常情况下,它们承诺会神奇而快速地提升性能,但结果往往是影响微不足道,甚至会使情况变得更糟。
许多公司将他们的开发人员视为纯粹的交付团队,也就是说,他们被用来实现基于产品管理的领导层和利益相关者定义的路线图的功能。为什么这是一场闹剧,参见马蒂·卡根(Marty Cagan)的帖子“为什么产品失败?”用这种方法,你只能得到其价值的一半。此外,公司认为开发团队可以很容易地被替换甚至外包。他们被当作雇佣兵对待,但正如我们从约翰杜尔那里了解到的那样。
为了最大限度地利用你们的开发团队,你们必须雇佣传教士并赋予他们权力。授权的开发人员是一流的员工。您的开发人员是最好的创新来源,因为他们了解使能技术。但很难吸引、认同和留住顶尖人才。请看,如何招聘(11.来自乔尔的测试)并留住最优秀的人才。
授权的开发人员不仅应该实现利益相关者的预定义功能,还应该被邀请提出自己的解决方案来满足客户需求。因此,我们应该让开发人员解决问题,而不是实现功能。开发人员必须了解业务上下文。快速自我检查您是否已授权开发人员:
他们知道客户的痛苦吗?或者他们被利益相关者、业务部门、项目经理和永远没有机会与客户接触的高墙挡住了?
您的开发人员是开发他们自己的特性,还是他们只在冲刺规划阶段获得这些特性?
(该公司)正在从技术团队性别歧视“服务于企业”的模式转变为“以服务于企业的方式服务客户”的模式。
像谷歌、亚马逊、Facebook、微软或Netflix这样的数字公司都有这些特点,他们已经靠这些标准生活了几十年。对他们来说,“软件”是他们的核心产品,他们负担不起堆积技术债务,因为他们会使自己的未来陷入瘫痪,并冒着风险。这一点他们是很清楚的。与非数字化公司的老式企业、IT部门和外包IT相反。
非数字化企业从来不认为“软件”是一种竞争优势。但慢慢地,就连他们也明白了“软件吞噬了世界”,他们想再次在内部开发软件。在这种情况下,缺少专有技术和“错误的”缺乏技能的人是很常见的。本文希望通过良好的实践,为他们树立良好的编码心态和文化提供一条简便易行的指导思路。我希望你能应用完整的测试,对你的公司或团队的优势、劣势和可能的改进有一些洞察力。