|
契约在软件上最基本的体现就是函数。当一个函数被定义出来时:它告诉它的使用者,你我之间应该如何合作。
比如说,一个函数可以是这样定义的:如果你传递给我类型为 X 的数据,我会返回给你类型为 Y 的结果,而且如果你传递相同的值进来,我给你相同的结果。这是 pure function,也是程序员最喜欢的契约形式,因为黑纸白字,清清楚楚,童叟无欺。
更普遍的情况是不那么纯粹的函数:如果你传递给我类型为 X 的数据,我会返回给你类型为 Y 的结果,当然,如果结果不存在,我会给你个 null,爱谁谁;而且,如果我中间处理的过程出了差池,我会扔一颗或者若干颗叫「异常」的**,咱俩要么哥俩好(你处理异常),要么同归于尽(不处理)。此外,我不能保证你传递相同的值进来,都返回给你相同的结果(比如说数据库操作)。有副作用的函数尽管有诸多含混不清的地方,任然不失为一种契约。
函数级别的契约的所有当事人都是程序员,契约更新的影响面有限,所以遇到问题,姐弟俩一商量,改!新的契约就出现了。然而,新的契约出现并不意味着旧的契约的终止,只有当所有使用旧契约的地方都改用新契约时,我们才能安全地废除旧契约。就一个函数来说,如果是两人之间的事,更换契约也就是个把小时的事情;然而,像 linux 这样复杂的系统,你改一个 list_add_tail() 的接口试试(假设你有权限),即使 Linus 不拍死你,我保证社区的口水也要淹死你。为啥?你触动了很多人的奶酪。
铺垫了这么多,就是想说明一件事:一旦你制定了一纸契约,你必须遵守它,且不要轻易改动它;使用契约的人越多,改动的代价越大。我们定义一个陈氏指数 CEI —— 契约使用指数(Contract Employ Index),每百万使用者记为 1。CEI 越高,表明使用者越多,同样的,改动的代价就越大。
REST API(以下凡提到 API,都指 REST API)是什么?REST API 是服务器和客户端之间的契约。这就意味着一个中小规模的 API,其 CEI 起码在 0.1 以上。API 一旦发布,你基本失去了对其任意修改的权利,因为你无法期待脱离了掌控的客户端能够像我们希望的那样,步调一致地升级系统。
所以,即便你习惯于随心所欲地创建一个函数,然后在需要的时候重构之,做 API 时,你会受到很多掣肘。老子说:「夫轻诺必寡信,多易必多难」,你一开始随意了,简单了,会给之后的维护和更新带来无穷无尽的痛苦。
|
|