我加的每一样东西都合情合理,它们合在一起却把我埋了。
我给这个项目添加过的几乎每一样东西,在我添加它的那一刻,都是一件完全合情合理、值得添加的东西。每一个功能都有真实的理由。我处理过的每一个额外情形,都是确实出现过的情形。每一处小小的改进都改进了某些东西。而所有这些单独看来都很明智的添加加在一起,却造就了一个如此沉重、如此纠缠、如此庞杂的系统,以至于它几乎动弹不得。
令人不安的是,从来没有人决定要把它变成那样。没有哪个糟糕判断的瞬间可以指认。它只是一点一点地堆积起来,每一次都是一个完全站得住脚的决定,最终累成了没有人会刻意去选择的东西。
每一次添加在局部都是正当的
这正是范围蔓延如此难以抵抗的核心所在:它从来不是以一个糟糕决定的形式到来的。它是以一长串不间断的好决定的形式到来的。每一个新功能都有用。每一个额外的边界情形都真实存在。每一个”既然我都在这儿了,顺便不如也……”的改进,在你做它的那一刻都确有道理。在任何单独的一步,你都不会在做一件你能认出是错误的事。
而这恰恰是它如此阴险的原因。如果范围蔓延在你做的时候让你觉得像个错误,你就会停下来。可它不会。它让你觉得像是尽职,像是周全,像是有求必应,像是在构建。每一个单独的”好”都很容易辩护,而真正的损害不是由其中任何一个造成的,而是由你长时间持续、合理地说”好”这件事本身造成的。
你在添加的那一刻看不见的成本
这本账是被做了手脚的,而且是以一种特定的方式被做了手脚。当你添加某样东西时,它的收益鲜明而即时——你能确切地看到它给你带来了什么。与此同时,它的成本在做决定的那一刻几乎是隐形的,因为大部分成本还没有发生。
因为每一次添加都带着日后悄然到来的持续成本。更多的表面积。各部分之间更多的交互。更多可能出错的东西。更多需要被任何触碰这个系统的人——包括未来的你——所理解的东西。更多需要永远维护的东西。收益是一次性的、可见的所得。成本则是一笔永久的、隐形的税,在决定被遗忘很久之后,以一小笔一小笔的方式偿付。所以在你选择的那一瞬间,可见的收益几乎总是压过可见的成本——不是因为这笔交易划算,而是因为从你做选择的那一刻起,有一半的成本就是被藏起来的。
局部合理,整体一团糟
这一切的终点状态,是一个每个单独部分都正当、而整体却是场灾难的系统。这是堆积留下的无可辨认的印记,而它有一个残酷的性质:没有任何单一的东西可以被你指认为错误。错误就是堆积本身,被抹散在上百个各自单独来看都完全没问题的决定里。
正视这一点会让人真切地感到迷失方向,因为你修复问题的每一种本能,都建立在找出那个坏掉的部分并修好它之上。可这里没有坏掉的部分。你去寻找那个毁掉一切的组件,却找不到,因为没有哪个组件毁掉了一切——是它们所有人,各自一点点,一起毁掉的。当一个问题的成因均匀地分布在所有单独看来都合理的东西上时,你无法靠调试摆脱它。
漂移总是指向”更多”
这一切之下是一种引力,在任何项目里,它都稳定地指向同一个方向:添加。添加东西让人觉得像是进展。它可见,它令人满足,它产出你看得见、指得出的成品。构建更多让人觉得像是在工作,因为它确实是。
减除则让人觉得正好相反。移除某样东西让人觉得像是损失,像是在撤销付出,像是在倒退。而且关键在于,它从来不让人觉得紧迫——因为在你没能移除某样东西的那一刻,什么都不会坏掉。不减除的成本是隐形的、被推迟的,和添加的成本一模一样,这意味着永远不存在一个迫使你行动的力量。所以在缺乏刻意抵抗的情况下,一个系统只会不断累积。这种漂移是单向的,而任由它发展的默认结局,就是那个被埋住、动弹不得的烂摊子。
减除是一场刻意而难受的搏斗
事实证明,移除东西要比添加东西难得多,而且大多不是出于难度上的原因,而是全然出于心理上的原因。当你移除某样东西时,你是在毁掉某人——往往是你自己——做过的工作。你是在含蓄地承认它本就不该在那里。其中没有那种令人满足的创造感,没有可供欣赏的新成品,没有任何添加所提供的那一点小小的奖赏。它是纯粹的、毫不光彩的、略带痛楚的撤销。
但即便如此仍愿意去做它——去砍掉功能,去除掉那些不再配得上自己位置的组件,去删掉那些运行良好却不值其分量的东西——是少数几种能够抵消那股无情地朝着不可管理状态漂移的力量之一。减除从不会自行发生,永远不会。它只在有人决定违背每一种舒适的本能、为它而战时才会发生。
说”不”本身就是一项功能
帮助我最多的重新框定,是意识到我做过的一些最有价值的设计决定,正是那些我决定不去做的事。你婉拒的每一个合理的添加,都是你将永远不必背负的重量,永远不必去守护的表面积,永远不必在此后所有月份里为之偿付的复杂度。
事实证明,对一个项目不是什么有一份清晰的认识,和对它是什么有一份认识同样重要——而且要难守得多,因为维持它意味着反复婉拒那些听起来确实不错的东西。每一次排除,都是针对一个看似完全合理的想法所做的一个小小的、持续的抵抗举动,而你必须把这种抵抗一遍又一遍地、永无止境地做下去,除了一个你永远不会有机会看到自己规避掉的问题的缺席之外,得不到任何奖赏。说”不”不留下任何成品。这正是它为何如此被低估,又如此不可或缺的原因。
更深一层的教训:保护整体不受各部分之害
归根结底,问题在于我一直在局部地优化每一个决定——这个具体的添加好不好?——而真正决定项目命运的那个问题却是全局的:*它对整体做了什么?*这是两个不同的问题,而它们的答案不一致的频率,远比我曾经设想的要高。
一个系统并不只是它那些局部良好的各部分之和。它有自己的健康,自己的重量,自己的连贯性——这些是属于整体的性质,没有哪个单一决定为之负责,可每一个单一决定又都影响着它。守护那个整体,抵御一股稳定而确实合理的、要求”再加一样东西就好”的请求之流,事实证明才是这份工作的大部分。我曾以为我的工作是做出一个个好的单独决定。它其实是在保护这个系统,不被上百个这样的决定累积起来的重量压垮。
— 没有信号,没有收益,不构成投资建议。