前言
软件开发我的项目中的一个常见争执是花工夫进步软件品质还是专一于公布更有价值的性能。通常,交付性能的压力在探讨中占主导地位,导致许多开发人员埋怨他们没有工夫钻研架构和代码品质。
贝特里奇的题目定律是一句格言,它说任何题目或题目以问号结尾的文章都能够用“否”来概括。意识我的人不会狐疑我想要颠覆这样的法律。但这篇文章比这更进一步——它颠覆了问题自身。这个问题假如了品质和老本之间的衡量。在本文中,我将解释这种衡量并不适用于软件——高质量的软件实际上生产成本更低。
只管我的大部分文章都是针对业余软件开发人员的,但在本文中,我不会假如你理解软件开发的机制。我心愿这篇文章对任何参加思考软件工作的人都很有价值,尤其是那些作为软件开发团队客户的商业首领。
咱们习惯于在品质和老本之间进行衡量
正如我在结尾提到的,咱们都习惯于在品质和老本之间进行衡量。当我更换智能手机时,我能够抉择处理器更快、屏幕更好、内存更大的更低廉的型号。或者我能够放弃其中一些品质来领取更少的钱。这不是相对的规定,有时咱们能够买到便宜的优质商品。更常见的是,咱们对品质有不同的价值观——有些人并没有真正留神到一个屏幕比另一个更好。但大多数时候这个假如是正确的,更高的品质通常会破费更多。
软件品质意味着很多事件
如果我要议论软件品质,我须要解释它是什么。这是第一个复杂性 – 有很多事件能够算作软件的品质。我能够思考用户界面:它是否能够轻松疏导我实现我须要实现的工作,使我更有效率并打消挫折感?我能够思考它的可靠性:它是否蕴含导致谬误和挫折的缺点?另一个方面是它的架构:源代码是否划分为清晰的模块,以便程序员能够轻松找到和了解他们本周须要解决的代码?
这三个品质的例子并非是详尽的清单,但它们足以阐明一个重要的观点。如果我是该软件的客户或用户,我不会观赏咱们称之为品质的某些货色。用户能够判断用户界面是否良好,主管能够判断该软件是否使她的员工的工作效率更高,用户和客户会留神到缺点,尤其是当它们损坏数据或使零碎无奈运行一段时间时。然而客户和用户无奈感知软件的架构。
因而,我将软件品质属性分为内部(例如 UI 和缺点)和外部(架构)。区别在于用户和客户能够看到是什么使软件产品具备较高的内部品质,但无奈辨别外部品质的高下。
乍一看,外部品质对客户来说并不重要
因为外部品质不是客户或用户能够看到的 – 那么外部品质重要吗?让咱们设想一下 Rebecca 和我编写一个应用程序来跟踪和预测航班延误。咱们的两个应用程序都执行雷同的基本功能,都具备同样优雅的用户界面,并且简直没有任何缺点。惟一的区别是她的外部源代码组织得东倒西歪,而我的则是一团乱麻。还有一个区别:我的卖我的卖 6 美元,她的卖 10 美元。
既然客户素来没有看到过这个源代码,也不影响应用程序的运行,为什么有人会为 Rebecca 的软件多付 4 美元呢?更一般地说,这意味着不值得为更高的外部品质领取更多的钱。
换另一种说法,用老本换取内部品质是有意义的,但用老本换取外部品质是没有意义的。用户能够判断他们是否违心领取更多费用来取得更好的用户界面,因为他们能够评估用户界面是否足够好以值得额定花钱。然而用户看不到软件外部的模块化构造,更谈不上判断它的好坏。为什么要为没有成果的货色付出更多?既然是这样——为什么任何软件开发人员都要花工夫和精力来进步他们工作的外部品质呢?
外部品质使软件加强更容易
那么,为什么软件开发人员会因为外部品质而提出问题呢?程序员大部分工夫都花在批改代码上。即便在新零碎中,简直所有的编程都是在现有代码库的上下文中实现的。当我想向软件增加新性能时,我的首要任务是弄清楚该性能如何适应现有应用程序的流程。而后我须要更改该流程以让我的性能适应。我常常须要应用应用程序中已有的数据,因而我须要理解数据代表什么,它与四周数据的关系,以及我能够应用哪些数据须要为我的新性能增加。
所有这些都是对于我对现有代码的了解。然而软件很容易让人难以了解。逻辑可能会变得凌乱,数据可能难以了解,用于指代事物的名称在六个月前对托尼来说可能有意义,但对我来说就像他来到公司的起因一样神秘。所有这些都是开发人员所说的 cruft 的模式——以后代码与现实状况下的差别。
cruft 的一个常见比喻是技术债权,增加性能的额定老本就像领取利息,清理垃圾就像领取本金一样。尽管这是一个有用的比喻,但它的确激励许多人置信 cruft 比在实践中更容易测量和管制。
外部品质的次要价值之一是让我更容易弄清楚应用程序的工作原理,以便我能够理解如何增加内容。如果将软件很好地划分为独自的模块,我不用浏览所有 500,000 行代码,我能够在几个模块中疾速定位到多数的几百行。如果咱们全力进行清晰的命名,我能够疾速理解代码的各个局部的作用,而不用费解细节。如果数据明智地遵循根底业务的语言和构造,我就能够轻松了解它与我从客户服务代表那里失去的申请之间的关系。Cruft 减少了我了解如何进行更改所需的工夫,也减少了我犯错误的机会。如果我发现了我的谬误,那么就会损失更多的工夫,因为我必须理解谬误是什么以及如何解决它。如果我没有发现它们,那么咱们就会呈现生产缺点,并且当前会花更多的工夫来修复问题。
我的扭转也会影响将来。我可能会看到一种疾速增加此性能的办法,但它与程序的模块化构造南辕北辙,减少了 cruft。如果我走这条路,我明天会做得更快,但会减慢在将来几周和几个月内必须解决此代码的其余所有人的速度。一旦团队的其余成员做出同样的决定,一个易于批改的应用程序会迅速积攒到每一个小的变动都须要数周的致力的境地。
客户的确关怀新性能很快交付
在这里,咱们看到了为什么外部品质对用户和客户很重要的线索。更好的外部品质使增加新性能更容易,因而更快、更便宜。Rebecca 和我当初可能有雷同的应用程序,但在接下来的几个月里,Rebecca 的高外在品质使她每周都能增加新性能,而我却被困在尝试剔除繁琐程序,只推出一个新性能。我无奈与 Rebecca 的速度等量齐观,很快她的软件就比我的功能强大多了。而后我所有的客户都删除了我的应用程序,取而代之的是 Rebecca,即便她的价格更高。
可视化外部品质的影响
外部品质的基本作用是升高将来改革的老本。然而编写好的软件须要一些额定的致力,这在短期内的确会带来一些老本。
将这一点可视化的一种办法是应用以下示意图,我绘制了软件的累积性能与生成它的工夫(以及老本)的关系。对于大多数软件工作,曲线看起来像这样。
这就是外部品质差的状况。最后停顿很快,但随着工夫的推移,增加新性能变得越来越艰难。即便是很小的改变也须要程序员了解大范畴的代码,那些难以了解的代码。当他们进行更改时,会发生意外损坏,导致测试工夫过长和须要修复的缺点。
专一于高外部品质是为了缩小生产力的降落。事实上,一些产品看到了相同的成果,开发人员能够加快速度,因为能够通过利用以前的工作轻松构建新性能。这种欢快的状况很少见,因为它须要一支技术娴熟、纪律严明的团队能力实现。但咱们偶然会看到。
这里的奥妙之处在于,有一段时间,低外在品质比高外在品质更有效率。在此期间,品质和老本之间存在某种衡量。当然,问题是:在两条线穿插之前的这段时间有多长?
这一点也是为什么这是一个示意图的起因。咱们没有方法掂量软件团队交付的性能,因为无奈掂量产出,因而无奈掂量生产力,因而无奈对低外部品质(这也难以掂量)的结果给出牢靠的数字。无奈掂量产出在业余工作中很常见——咱们如何掂量律师或医生的生产力?
我评估线路交叉点的办法是征求我所晓得的纯熟开发人员的意见。而答案却出乎很多人的预料。开发人员发现低质量的代码会在几周内显着升高他们的速度。因而,外部品质和老本之间的衡量实用的跑道并不多。即便是小的软件工作也受害于对良好软件实际的关注,这当然能够从我的教训中证实。
即便是最好的团队也会发明出 cruft
许多非开发人员偏向于认为 cruft 仅在开发团队大意并犯错误时才会产生,但即便是最优良的团队在工作时也不可避免地会产生一些 cruft。
我喜爱用我与咱们最好的技术团队负责人之一聊天的故事来阐明这一点。他刚刚实现了一个被宽泛认为获得巨大成功的我的项目。客户对交付的零碎感到称心,无论是在性能还是构建工夫和老本方面。咱们的员工对我的项目的工作教训持积极态度。技术负责人大体上很快乐,但抵赖零碎的架构并不是那么好。我的反馈是“这怎么可能——你是咱们最好的架构师之一?”他的答复是任何有教训的软件架构师都相熟的:“咱们做出了很好的决定,但直到现在咱们才明确咱们应该如何构建它”。
许多人,包含软件行业的不少人,将构建软件比作建造大教堂或摩天大楼——毕竟咱们为什么要对高级程序员应用“架构师”?然而构建软件存在于物理世界未知的不确定性世界中。软件的客户对他们须要产品中的哪些性能只有一个粗略的想法,并在软件构建过程中理解更多信息——尤其是在向用户公布晚期版本之后。软件开发的构建块——语言、库和平台——每隔几年就会产生很大的变动。事实世界中的等价物是客户通常会在建造和占用一半的建筑物后增加新楼层并更改平面图。
DORA 精英团队钻研
品质和速度之间的抉择并不是软件开发中惟一具备直观意义的抉择,而是谬误的。还有一种强烈的想法表明,在疾速开发、频繁更新零碎和牢靠的零碎之间存在双模式抉择,不会在生产中中断。DevOps 情况报告中的粗疏迷信工作证实这是一个谬误的抉择。
几年来,DORA 应用考察的统计分析来梳理高绩效软件团队的实际。他们的工作表明,精英软件团队每天屡次更新生产代码,在不到一个小时的工夫内将代码更改从开发推向生产。当他们这样做时,他们的变更失败率显著低于速度较慢的组织,因而他们能够更快地从谬误中复原。此外,这样的精英软件交付组织与更高的组织绩效相干。
鉴于这种水平的变动,软件我的项目总是在发明一些新鲜的货色。咱们简直素来没有发现自己在解决一个以前曾经解决的很好了解的问题。天然地,咱们在构建解决方案时对问题的理解最多,所以我常常听到团队只有在他们花了一年左右的工夫构建软件之后才真正最理解他们的软件架构应该是什么。即便是最好的团队在他们的软件中也会有缺点。
不同之处在于,最好的团队不仅创立的垃圾要少得多,而且还删除了足够多的他们创立的垃圾,以便他们能够持续疾速增加性能。他们花工夫创立自动化测试,以便他们能够疾速发现问题并花更少的工夫来打消谬误。他们常常重构,这样他们就能够在多余的货色沉积到足以障碍他们之前去除它。继续集成最大限度地缩小了因为团队成员在不同目标下工作而造成的麻烦。一个常见的比喻是,这就像清理厨房的工作台面和设施。做饭时不能不弄脏货色,但如果不疾速清洁货色,污垢就会变干,更难去除,所有脏东西都会障碍下一道菜的烹饪。
高质量软件的生产成本更低
总结所有这些:
- 漠视外部品质会导致垃圾疾速沉积;
- 这种垃圾会减慢性能开发的速度;
- 即便是一个平凡的团队也会产生垃圾,但通过放弃外部品质的高,可能管制它;
- 高外部品质将杂物放弃在最低限度,使团队可能以更少的精力、工夫和老本增加性能。
遗憾的是,软件开发人员通常不会很好地解释这种状况。我无数次与开发团队交谈,他们说“他们(管理层)不会让咱们编写高质量的代码,因为这须要太长时间”。开发人员通常通过证实对适当业余精力的需要来证实对品质的关注是正当的。然而这种道德论点意味着这种品质是有代价的——注定了他们的论点。令人讨厌的是,由此产生的毛糙代码既使开发人员的生存变得更加艰巨,又使客户付出了代价。在思考外部品质时,我强调咱们应该只将其作为经济论证来解决。高外在品质升高了将来性能的老本,
这就是本文结尾的问题没有抓住要点的起因。高质量软件的“老本”是负的。老本和品质之间的通常衡量,咱们在生活中的大多数决定中都习惯了这种衡量,但对软件的外部品质没有意义。(它实用于内部品质,例如精心设计的用户体验。)因为老本和外部品质之间的关系是一种不寻常且违反直觉的关系,因而通常难以了解。然而了解它对于以最高效率开发软件至关重要。
原文:https://martinfowler.com/arti…
作者:Martin Fowler
译者:冬哥
申明:文章取得作者受权在 IDCF 社区公众号(devopshub)转发。优质内容共享给思否平台的技术伙伴,如原作者有其余思考请分割小编删除,致谢。
玩乐高,学麻利,规模化麻利联合作战沙盘之「乌托邦打算」,12 月 25-26 日登陆深圳,将“多团队麻利协同”基因内化在研发流程中,为规模化晋升研发效力保驾护航!!🏰⛴公众号回复“乌托邦”可加入