这是来自于黑客的行话(jargon),对于软件设计来说还是很有借鉴意义的一条经验原则,作为一种推演法的思考方式,相信对于其他领域应该也是有所裨益的。
黑客行话档案(Jargon Files)这样介绍的:
"不允许foo实例,允许一个foo实例或者允许任意的foo实例。"(译者注:软件开发者通常使用foo作为类设计的示例),一个软件设计的大拇指规则(Rule of Thumb),告诫不要随意的限制一个给定实体的实例数(例如:窗口系统的窗体数,操作系统文件名的字符数等)。更明确一些,一个实体要么完全不允许,要么允许恰好一个实例(一个“特例”),或者允许任意用户需要的——如地址空间或者内存使用。
隐藏在规则背后的逻辑是指在大多数情况下可以很清楚的知道需要一个而不是无。然而,如果更进一步,允许N(N>1),那为什么不是N+1呢?如果允许N+1,那为什么不是N+2?一旦超过1,并没有理由不允许任意的一个N;因而,就应当是无穷。
很多黑客还记得艾萨克.阿西莫夫(注1)的科幻小说"The Gods Themselves"中的一个人物说2是不会发生的——如果你相信有超过一个的宇宙,那么你也可以相信有无限个宇宙。
-------
原文参见:Online Jargon Files
真的不存在"2"或特定的"N"吗?自行车有两个轮子,但也有三轮的自行车,四轮也未尝不可,似乎合理。但性别呢?方向(东南西北/左右/上下)?似乎在我们的认知条件下或从某种角度,也存在一些事物有固定的实体数量。
在数学和哲学领域我们可以很容易的表达无穷,它只是一个符号或一种象征,但在真实世界里通常是无法表达的。地球上的各种物质资源都是有限的,宇宙恐怕也是,即便一颗遥远恒星的重量超过我们的想象。有名的计算机"千年虫"问题,因为当时的设计者关于日期位数不周全的限制而带来了一场二十世纪末的恐慌,那么现在是否就彻底解决了这种限制了呢?现在的计算机时钟几百年、几千年后也不会再出现这个问题,但是千万年、亿年后呢?目前采用的年数表达方式也会出现"千万年虫问题"或者"亿年虫问题",因为计算机的资源是有限的,并不能真正表达一个无限的日期。就这个问题来说,这种考虑是没有必要的,没有人会担心这个问题——如果一百年或者几百年不会出现问题,那么就解决了,遥远的未来谁想去知道呢?大多数时候,“无限”并非真正需要。
在设计中考虑Zero-One-Infinity规则,有助于系统获得更好的扩展性。例如一个软件要适应两个领域或被五个用户使用,一个模块被两个或更多的地方调用,那么就应当考虑适应更多的领域,满足更多用户的通用特征,为模块提供扩展的机制以便更多的地方可以调用。
因此,我们在设计时考虑Zero-One-Infinity规则以消除对将来扩展不利的限制,而实现时则需要考虑在有限资源和价值下的"Infinity",采用有限的方式来表达无限,例如根据请求分配内存(对用户感觉是无限大)、无上限集合,一个足够大的数组,以及可扩展的结构。
很多经验开发方法,例如极限编程(eXtreme Programming),还强调平衡考虑扩展性的时机和代价,从简单设计开始,考虑当前的需要(1或者N的情况),当出现冗余设计(N+1)的时候,才决定是否设计为可扩展的结构(Infinity)。重构(Refactoring)的一种有效做法就是发现冗余代码(N>1),将它们通过某种形式提取出来,以便更多(Infinity)的地方使用。这也是人力、时间、机会成本等有限资源下对“无限”的实效价值观点的表达方法。
其实这条规则在现实生活中也有可参考之处。史蒂芬.茨威格(Stefan Zweigs)在《昨日的世界-一个欧洲人的回忆》中曾提到,他到十月革命后的俄国去旅行时,发现俄国人喜欢批条子、签文件而不是像奥地利人那样通过制定法律来处理事务。在我看来,批条子干的就是一个又一个“N”的事,而制度则可以应付“Infinity”类似的事务,当然现实和人远比这条规则复杂得多。
-------
[1].艾萨克.阿西莫夫(Isaac Asimov,192O-1992) ,美籍犹太人,为本世纪最顶尖的科幻小说家之一。“基地”、“机器人” 等系列是艾西莫夫最脍炙人口的代表作。2004的科幻电影"I, Robot"即改编自阿西莫夫的机器人系列。
(本文也发表在作者的另一个blog上)