1.4 软件行业中的奥卡姆剃刀
奥卡姆剃刀是由 14 世纪方济会修士奥卡姆的威廉提出的一种逻辑学原则,这个原则是这样表述的:
"切勿浪费多余功夫去做本可以较少功夫完成之事"。
按照流行的话来说就是"如无必要,勿增实体"(这句翻译的出处已经不可考)。
要理解奥卡姆剃刀,需要理解当时的历史背景。 14 世纪是经院哲学如日中天的时期,经院哲学为了证明上帝存在性发明了大量的哲学概念和要素,始终讨论无休无止的"本质"。哲学家提出了一个概念,为了解释这个概念需要更多的概念来修补,陷入大量无意义的讨论。
这些讨论非常类似于我国的魏晋时期,魏晋时期人们热衷于讨论玄学,讨论世界的本源。在西方这类讨论被我国的翻译家叫做形而上学,形而上学在亚里士多德的《形而上学》中实际上是"如何做学问的学问",仍然属于哲学范畴,并非完全一样。
奥卡姆的剃刀原则并非减少了形而上学的讨论,而是将逻辑学、哲学、自然科学、神学分开,他主张不能将神学的讨论纳入逻辑学中。逻辑学是关于概念、推理和语言上的学问,哲学是关于如何思考的学问,自然科学是关于具体事物的学问,上帝的问题留给神学来讨论。
因此,富有逻辑的人应该使用尽可能少的要素来解释更多的问题,而不是无休无止的引入学说,打上大量的补丁。
但是需要警惕的是,奥卡姆剃刀容易被伪科学人士当做工具用来攻击专业且复杂的学术理论。奥卡姆剃刀背后的本质是,对认知理解越深入,需要解释的就越少。甚至有人认为,奥卡姆剃刀的思想触发了随后的宗教改革和文艺复兴。
也就是说,如果我们能找到解释繁杂问题的根本原因,就不需要太多的概念和文字描述。有时候有人洋洋洒洒写了好几千字的文章,但是富有洞见的人却能用一句话表述出来。反过来看,如果暂时不能找到更简洁的理论,就依然得使用现存的理论,寻找终极简洁的理论是目前物理学在始终追求的目标。
举个例子,看似繁复的领导力问题实际上在一些"粗鄙"的江湖人士中,会这样表述:
"别人愿意和你一起干,作为领导者,你能保护他们,且让他们吃到肉。"
这里的肉是一个绝妙的比喻,含义是处于组织中的个体,是以自由的让渡作为代价,换取组织的保护,以获取比个体更多的价值。
保护不仅仅是安全,譬如合理的工作方式、良好的环境都算作保护。在企业工作的员工,并非喜欢打工,而是相比单独讨生活,在公司工作可以获得更合理的工作流程、更舒适的工作环境和更高的报酬。当一名员工可以独立企业之外,获得想要的一切时,他没有动机继续留在企业中。我们并不能使用道德来评价这些现象。
奥卡姆剃刀的启发性是它最重要的价值。在自然科学、社会学的中有大量的案例和应用场景,最著名的例子是爱因斯坦用它大胆的否定了以太学说。
19 世纪的物理学家们,为了找到电磁波和光的传输介质,提出了以太这种假象中的物质。以太最初来自亚里士多德,虽然它的概念随着历史发展不断变化,但是它是非常重要的一种假想物,用来解释是什么填充无穷的宇宙。
但是非常麻烦的是,引入以太这个概念,不仅没有解决物理学的问题,反而让很多问题变得更加复杂。1905 年爱因斯坦大胆抛弃了以太说,认为光速不变是基本原理,并以此为出发点之一创立了狭义相对论。
爱因斯坦因此说:
"Make everything as simple as possible, but not simple。让一切尽可能简单,而不仅仅是简单。"是数学中一种形式
思维经济原则可以看做奥卡姆剃刀的发展,用更清晰的方式诠释了奥卡姆剃刀的本质(注意很多文章将这两个理论混同了)。马赫认为"思维经济是科学的主要任务",也就是说,如果科学成果不能让复杂的事物简化,那么就没有起到应有的作用。
他认为科学研究是科学模型和待解决问题之间的模写(提取模型)。提取模型就好像做 HASH 算法,将复杂的现实抽象成简单的公式。模写是简单化和抽象化思维,这种思维有经济性(不费力理解的一类更受欢迎)的倾向。思维经济性原则对世界起到巨大的影响,大量的理论出现然后按照经济性被选择下来,人类因此获得更优的理论。
奥卡姆剃刀被应用到最有趣的地方是应用到刑侦技术中,因为往往众多的假设中,对犯罪嫌疑人来说思维成本更低的最有可能,大部分场景下不太可能出现高明、精巧的作案方式。
奥卡姆剃刀也可以应用到软件工程中来,用一些模型简化业务问题。甚至能用模型简化软件开发过程中的模型,这种模型更加抽象叫做元模型,我会在后面专门聊模型思维的时候详细阐述。
作为架构师,需要对技术选型,找到合适的技术组件来完成业务目标。如果使用奥卡姆剃刀原则,就可以剔除思维过程中的杂质,直接对问题寻找更简洁和经济的方案。例如,一个客户找到我们需要建立一个数据湖,实际上当我们分析问题后发现他们仅仅需要一个简单的数据同步机制,而通常意义上的数据湖也具备这样的能力,给客户带来了认知干扰。
有一些违反奥卡姆剃刀原则的原因可能是人们在工作中逐渐忘记了目标和手段。
比如在一个电商程序中,如果一个发货单有 "拣货中"、"打包完成"、"运送中"、"妥投" 等状态,我们需要确保状态的并发操作正确。两个业务动作(打包和物流揽收)会导致系统产生两个请求:
A 请求要把状态更新为 "打包完成" 。 A 请求要把状态更新为 "打包完成" 。
B 请求要把状态更新为 "运送中" 。 B 请求要把状态更新为 "运送中" 。
由于种种原因 B 请求先被响应了,A 请求后被响应,如果不做控制,单据的状态就会变成了"打包完成",而不是我们预期的"运送中"。
有朋友希望引入一套分布式锁机制来完成这个业务。通过奥卡姆剃刀原则来指导分析,我们会发现如果处理 "运送中" 的状态,必须检查已经是 "打包完成" 才会继续,如果条件不满足就让 B 请求报错即可。
在这个场景中,它的目的是避免异常数据的产生,分布式锁并不是目的,可能仅仅是因为习惯引入了分布式锁。这个场景下,其实可以用更简单的方法清晰的解决这个业务需求,节省大量的工作量。
总之,奥卡姆剃刀原则、思维经济原则给了我们一个很好的启示,用来评价什么是一个好的模型。不过,我们总是应该反过来思考,奥卡姆剃刀原则的局限性是什么?
"奥卡姆剃刀并没有说简单的假设就一定更好。[12] " 有人开始将奥卡姆剃刀当做一种真理,这显然是违背科学原则的。当我们在横向对比诸多模型时,我们可能偏好选择简单的那个,但是需要建立在这些模型都能良好的描述研究对象才行。
在没有更简洁的模型出现之前,也不得不承认我们的认知停留在这里,只能先使用复杂的模型。