近日,十多年从事开发工作的 Facundo Olano 写了一篇关于“软件开发应该优先服务谁”的文章,引发了广发开发者讨论。Facundo 在文章中提出,业务和用户的优先级永远大于维护者,维护者大于开发者,但对于业务和用户的优先级,则无法确定。
对此,有开发者提出,开发人员其实必须满足的是中层管理人员的需求,而不是实际用户的需求,否则就拿不到订单。那么,在这个研发生态里,开发者明显处于底层,那谁才处于“食物链的顶端”?
“代码的阅读次数大于编写次数。”相信很多程序员朋友都听过这句话,它提醒我们作为代码开发者,绝不应牺牲未来的阅读和修改空间来换取一己之便利。换句话说,代码的阅读量要多于编写量,所以最好想办法保证代码简洁明了,同时辅以测试和说明文档等有助于提高可维护性的要素。
我个人则将其总结为更简洁的表达方式:
维护者>作者
其实在代码编写之外,这样一条经验法则也同样适用于发现问题和做出决策。
代码是用来跑的,不是用来读的
代码只是我们达成目的的手段。软件都有自己的目的,负责为特定用户提供服务。如果代码无法达成这项目的、为用户提供良好的体验,那么无论代码本身质量多高、可维护性多棒、涉及的技术有多么精妙,都将毫无意义。因此:
用户>维护者>作者
或者说,我们把开发者部分统一起来,就得到了:
用户>开发者
正因为如此,我们才应该尽早、尽快把程序交付给用户,再结合他们的反馈不断做出优化,而不是在事前做一大堆假设、或者反复询问他们到底想要什么。
这是一套强有力的思维模型,只要在开发过程中始终以用户为中心,我们就能走得更远、更稳。这也是我自己在漫长的职业生涯中,总结出的最具指导意义的开发方针。
代码的运行次数大于阅读次数
当我说到“运行”时,指的可不只是执行程序,更包括生产运营中的各个环节:部署、升级、观察、审计、监控、修复、清退等。正如 Dan McKinley 所言:
“总的来说,保持系统长期可靠运行的成本,要远远优先于构建系统时遇到的种种不便。”
我们也可以把这个结论纳入前文提到的小模型:
用户 > 运维者 > 开发者
我本人花了很长时间才吃透这一点。因为根据个人经验,实际构建的很多软件都从未真正被投入生产,至少没有得到大规模应用。这是因为大部分软件都建立在未经测试的假设之上。
在生产环境中运行代码时,保持简单/保持傻瓜设计这看似直白的原则往往很难落地。它指的不只是代码本身,更要求减少软件中的活动部件、吃透软件的故障模式。换言之,要保证某些部件出了问题时软件仍能正常工作。
别忘了,是软件在为业务服务
要想让开发过程平稳推进,核心要素在于用户。而这其中蕴含的假设是:软件本身有用且运行良好,软件对用户有价值、对组织也有价值。这样的提前可以转化成以下理解方式:开发者需要编写出良好、可用的软件,业务部门再将其转化成经济收益。
另外,软件应该总体有效,更好地服务于消费者和企业需求。通过纳入业务视角,我们的基本方针进一步扩充成这样的形式:
业务 > 用户 > 运维者 > 开发者
最典型的例子就是预算:我们不可能有无限的资源来满足用户需求,所以首先要衡量成本和收益,想清楚怎样设置营销活动和上市期限。此外还有利益相关方和投资者,他们各有各有利益和诉求。
在如此复杂的情况下,乍看上去对于软件、开发团队或用户似乎正向的决策,放进整个组织内往往会起到负面作用。有时候,我们更需要创造收入、而不只是取悦用户。
反面教材
到这里我们就得到了一个小模型,表达了软件开发流程中各个因素之间的相对重要度,也许能帮助大家立足宏观专注于真正关键的环节。接下来,我们将着眼于常见的软件开发障碍,尝试把它们也纳入思维模型。
不可维护的代码:作者 > 维护者
这就是我们文章开头提到的情况,开发者聪明但太懒惰,于是写出的代码就成了交缠混杂的意大利面,后续的接手者永远无法理解当初为什么要这样设计。
无用的软件:开发者 > 用户
对于那些不在乎用户感受、或者坚持把技术放在首次的团队,开发的就是这种无用软件。其中充斥着过度设计、降低用户体验的“现代化”元素,Web 应用程序甚至有可能导致浏览器崩溃。
在我的机器上明明能跑:开发者 > 运维者
软件在设计中并未考虑到运维需求,因此软件本身过于复杂、包含大量移动部件、专供小型数据负载使用的数据库、由众多小团队管理的微服务生态等等。总之,软件架构在毫无必要时就开始考虑后续的规模扩展问题,最终运维人员被折磨得焦头烂额、开发人员也被批得体无完肤。
技术倒逼业务:开发者 > 业务
把代码本身视为目的。那帮自命不凡的工匠、泰坦尼克号上的音乐家和 Lisp 极客们,搞出来的就是这样的软件。
简历驱动型开发:开发者 > 一切
不加任何约束、任由开发者天马行空发挥之下,开发出的就是这种软件。
纯粹空想型软件:业务 > 用户 > ops 开发者
这种软件虽然能被开发出来,但却很少、甚至从未被投入生产。我个人称之为空想型软件,因为它完全是按照业务部门的想象搞出来的。
业务 > user >运维者 > 开发者
这是另外一种没考虑过用户需求的空想型软件,它根本就解决不了问题、或者解决的是错误/根本不存在的问题。这类软件会倒逼用户向它靠拢,为的就是让大量前期投资看起来能有那么一点点用处。
极端资本主义软件:biz > 用户 > 运维者 > 开发者
这是由风险投资支撑而来的软件,没有健康的商业模式,或者说商业模式只追求不断增长、达成垄断、剥削用户。
一点总结
最后,让我们为这场有趣的思想实验做个收尾:
业务 > 用户,这会带来难以估量的灾难后果。
如前文提到,我们之所以要开发软件,目的是为最终用户解决问题。《程序员修炼之道》就对此做出过精当的总结:我们的目标是取悦用户,而不仅仅是交付代码。但自从投身于程序开发之后,我发现随着软件普及度的不断提升,这个假设又变得越来越不受重视、难以维持。
当下很多得到大规模应用的软件根本就不关心用户,甚至反过来要操纵用户、把用户变成产品的一部分。这不仅限于社交媒体——作为用户,我们甚至无法回避各种页面和功能栏中的广告弹窗,谷歌搜索里显示的垃圾也越来越多。
在我看来,好软件的定义已经跟行业中大部分认为的能赚钱的软件之间出现了严重割裂,很多软件专家的强烈不适感也正来源于此。虽然我们不能忽视软件开发领域的底层商业逻辑,但至少应该采取更强硬的道德立场、拒绝无止境地伤害用户。用户也许并不永远优先于业务,但业务也不该被无条件地放在首位:
用户 > 运维者 > 开发者
业务 > 运维者 > 开发者
业务 ≹ 用户
网友:实际上你必须考虑管理层
Facundo 的文章引起了广发开发者共鸣,同时这些开发者们结合自己的实际经历又做了一些补充,比如管理层的关键作用。
有开发者直接指出,有些用户使用某个系统并不是因为他们喜欢它,而是因为他们的公司购买了它。“在‘业务>用户’的情况下,开发人员最终不得不迎合中层管理人员的需求,而不是实际用户。不这样做的代价就是无法赢得合同。但当你忙于实现中层管理喜欢的新功能时,用户的需求就会被锁定在你有限时间里能提供的‘垃圾’里。”
“我有过这样的经历。我在一家向市政府销售软件的公司工作。重要的是市长/镇长/市议会的意见。如果报告看起来不错并且价格合适,他们就会续订。我记得在会议现场,每天使用它的人当面告诉我们它有多么糟糕。毫无疑问,该网站承诺将修复一些特定的 bug,并将价格提高到最低限度。” 网友“Deprecate9151”提到。
“derangedHorse”指出,“通常,中层管理人员也是用户,但他们只占用户群的少数,并且使用一组不同的功能(例如报告)。因此,现在的问题是哪些用户被优先考虑,并在优先考虑少数拥有权力的用户的体验与保持产品足够的可用性以供其他用户提供一些数据价值之间找到平衡。”
对此,有开发者指出,“您需要考虑中层管理人员的需求,因为他们付钱给您,但通常还有工艺空间为最终用户带来真正出色的用户体验。大多数软件工程师都缺乏真正的工艺意识,因此当不需要构建出色的用户体验时,他们通常不会理会这个。”
参考链接:
https://olano.dev/2023-11-30-code-is-run-more-than-read/
https://news.ycombinator.com/item?id=38483181
评论 2 条评论