修改的成本
所需上下文、显性知识与隐性知识,以及为什么上下文成本是软件工程的共同货币。
本文为中文版,根据英文原版改写,而非逐句直译。
长期以来,软件行业一直把“可维护性”和“可读性”奉为首要的设计目标。但两者本身都不是目的。我们维护和阅读代码,在操作层面只有一个目的:修改它。开发者研究代码库,不是为了被动地理解它;他们阅读,是为了决定要改什么、要保留什么,以及如何安全地绕开各种约束。就连调试、评审和测试也不是独立的学科,而是这条更大的修改流水线中的辅助环节。它们的存在,是为了确认一次改动能否安全进行、应当放在哪里、执行得是否正确。
信息完备性
要正确地完成一次修改,开发者或 AI 智能体必须做到信息完备。一边猜测系统的约束,一边修改系统,是不可能可靠的。他们必须获取一组足够的事实,才能完成改动并保持预期的行为。我们把这组足够的信息称为一次修改的所需上下文(required context)。
上下文是完成一次改动所需的全部知识的总和。这些知识从根本上分为两种形式:显性的和隐性的。
- 显性上下文是正式编码在书面构件中的信息,包括源代码本身、schema、测试和文档。
- 隐性上下文是开发者必须记在脑子里、未被写下来的信息,包括运行时行为、隐藏的全局状态、历史决策、部落知识,以及框架看不见的副作用。
定义上下文成本
获取这些所需上下文,是修改在操作层面的核心负担。回忆上一章提到的修改四步:找到要改的地方,弄清要保持什么,决定改什么,确认改对了。走完这几步所花的力气,并不只取决于你需要阅读的信息总量,而取决于以足够的把握获取这些信息、确信自己的上下文已经完整所需的成本。
这其中包括上下文的规模、上下文的分散程度、到达它所需的遍历,以及找到它的路径是否可靠。开发者在设计糟糕的系统里感受到的焦虑,来自缺少一个可靠的停止点:你永远无法完全确定自己已经找到了所有约束或连锁影响;你只是在时间或耐心耗尽时停下,然后指望测试套件能兜住你漏掉的东西。
我们把这种操作负担称为上下文成本(Context Cost):为正确修改而获取充分上下文的成本。上下文成本不仅包括所需上下文的规模,还包括这些上下文如何到达、分布得有多广,以及修改者能有多可靠地知道已获取的上下文是完整的。
设计的货币
如果软件开发是一条连续不断的修改流,而每一次修改都需要获取充分上下文,那么获取上下文的成本就是软件工程的共同货币。
软件设计的目的由此变得非常具体:好的设计让上下文成本最小化。 它无关于遵从抽象的审美,无关于逐字逐句地执行原则,也无关于为了“整洁”而追求整洁。它关心的是,让现实中的修改所需的上下文更便宜、更安全、更可靠地获取。
当我们不再争论某个设计是否“优雅”,而开始追问未来的修改者需要携带多少上下文时,设计争论就褪去了教条色彩。我们不再以代码看起来如何来评判它,而是以它给下一位必须修改它的人带来的操作负担来评判它。