咖思漫 > 社会 > 正文

​奥卡姆剃刀原理、简单性原则与软件开发

2024-11-04 15:43 来源:咖思漫 点击:

奥卡姆剃刀原理、简单性原则与软件开发

奥卡姆剃刀原理是最强大的解决问题的原则之一,它可适用于生活和软件开发中。它可能不为人所知,而且经常被误解且没有得到充分的利用。

奥卡姆剃刀原理

奥卡姆剃刀原理在中文中被定义为:“如无必要,勿增实体”。它提倡:“当对于同一预测的多个竞争性假设时,人们应该选择假设最少的解决方案”。在没有证明假设之前,更应倾向于简单而非复杂。

奥卡姆剃刀原理也即最简单的方案往往可能就是最正确最好的方案,切勿浪费较多资源去做那些用较少资源也可以做好的事情。

简而言之,就是保持事情的简单性,要驭繁于简,而不要人为地把事情复杂化,自寻烦恼。

奥卡姆剃刀在科研、管理、投资等领域作为一种指导原则而广泛应用,在没有经验证据的状况下,它可以作为一种快速决策和建立真理的手段。在人工智能领域,机器学习的过程中,选择复杂性低一点的数学模型,算法的表现往往会更好。虽然奥卡姆剃刀不是在所有的场合都适用,但它是一个具有启发性的指导原则,其核心意义在于不要将已经很复杂的问题人为地更加复杂化,而在模型上化繁为简是相对正确的途径。

敏捷软件开发与奥卡姆剃刀原理

“敏捷软件开发”指的是在多次迭代中构建和测试软件的策略,因为软件每次只开发一小部分。敏捷的主要目标是快速交付可工作的软件,并且尽量没有bug。

敏捷开发

随着开发的继续进行,在开发过程中添加了更多的新特性,不必要的复杂性就会悄悄进入到项目中。这便导致了一项巨大的质量保证任务,即在最后审查一个庞大而复杂的系统。如果你将奥卡姆剃刀原理应用到流程中,就可以大大降低这种不必要的复杂性。

敏捷软件开发可能变得复杂,特别是在经过多次迭代之后的过程中。减少这种复杂性的并发症最好方法是将奥卡姆剃刀原理应用到这个过程中。每个软件团队应该从简单开始,只有在明确确定了要增加功能的需求后才增加复杂性。

在软件设计中,实现所需功能的最简单的代码通常是最好的。简单的代码不太可能有bug,通常程序运行得速度也会更快。

敏捷软件开发的复杂性是通过在迭代过程中,以小而频繁的形式添加,并最终小心的演变成最终产品。这种方式事半功倍,省时省力,避免不必要的错误和修正。向项目添加的复杂性越多,编码实现、测试和审查新添加内容所需的时间就越多。记住,系统越复杂,失败的概率就越高。

实现这种策略可以使软件更容易构想、构建和测试。保持事情尽可能简单,也有助于项目相关人士和最终用户,因为他们更愿意评估一个更简单的系统,而不是一个复杂的系统。通过应用奥卡姆剃刀原理,软件开发团队将取得更快的进展,并且随着项目的继续,将更容易应用更正。

软件架构设计与奥卡姆剃刀原理

为什么程序员之间的工作效率有巨大的差距?研究表明:相同经验和学历的两个程序员之间的生产力差异很容易相差一个数量级(10倍),而调试生产力的差异可能相差25倍。

软件架构

这些非常有生产力的程序员会编写简单、优雅、易于理解的代码,用很少的代码完成很多的事情。

这些“明星”程序员以大多数人都无法理解的方式来获得这些生产力。话虽如此,普通的程序员也可以通过做一些事情来提升自己的生产力来达到“明星”程序员的水平。

在某种程度上,明星程序员通过做的更少来完成更多的事情。这有点反直觉,但如果你考虑到一个程序员花时间写一些不必要的代码,或者不得不一致重构代码,只是因为他的设计不能简单处理不断变化的需求。那么他们将只有更少的时间来编写那些“需要的”代码,从而降低了生产效率。这些高产出的有效性可以部分通过奥卡姆剃刀原理和少做的原则来体现。

奥卡姆是14世纪的哲学家,他对软件一无所知。但是,他确实了解复杂性的问题以及简单性在所有事物中相应的有效性。

奥卡姆剃刀原理背后的原则是告诫人们以简单为重并通过剔除任何不直接支持结论的东西来实现这一目标

现代对奥卡姆剃刀原理经常会被解释成:“最简单的解决方案几乎总是最好的”。但是现代的解释忽略了重要的一点即:“最简单”意味着“假设最少”。这个原则也经常被称为“节俭原则”:“采用现有最简单或最简洁的解释”。

“街上的女士是个女巫--是她干的”,这句话是一个非常“简单”的、毫不含糊的陈述。它引入了很少的实体,并提供了一个简单的解释,最初看起来很像那么回事。但仔细分析,这句话是建立在几个非常大的假设之上的。这句话违法了奥卡姆剃刀原理,为了支持一个结论引入了不必要的实体:

1、女巫存在;

2、这个女士是女巫;

3、她干了;

4、她被任务是个女巫与她是否干了有关;

实际上,这些因素与她所谓的罪行没有任何联系,但如果我们不质疑他们的真实性就接受他们的话,很可能会导致一个错误的结论--她有罪。历史已经告诉我们,许多无辜的人基于这种似是而非的推理而被判处可怕的死亡。

当涉及到软件设计时,你确定你的推理没有类似的缺陷吗?你确定你所做的一切是真正为了支持项目目标而做的吗?你是否也不必要的引入了一些元素,认为它们是你计划的结果,结果仔细检查后发现并非如此?

幸运的是敏捷软件开发的一个主要优势是首先关注重要的事情。具体而言体现在:我们较少关注技术,而更多关注于为终端用户提供价值。

虽然有各种不同的评估,但一般都认为软件应用中80%的功能从未或很少被使用。使用敏捷软件开发可以确保我们在过程中不断的评估特性与功能并重新确定其优先级

通常,当我们接近项目的尾声时,我们意识到最初在需求列表中的大部分内容不再相关,但是因为我们在早期就交付了最高价值的功能,利益相关者也通常会在开发的早期就感到满意。通常他们会决定,许多最初要求的能力已经不再适用了。良好的开发方法论将精力集中在提供价值上,这对奥卡姆所倡导的原则有很大的帮助,但这还不够。

随着应用需求的扩大,软件解决方案的规模和复杂性也在不断增加。复杂性引入了不确定性,而不确定性意味着风险;风险越大,失败的概率越高。为支持一个结论增加实体并不只是增加复杂性,而是使复杂性成倍增加。

我们通过这个简单的例子说明了这一点:拿一张白纸和一支铅笔,在纸上画两个点,用一条直线把两个点连接起来。现在添加第三个点,并将其与另外两个点相连。你现在应该有三个点和三条线。现在添加第四个点,并将其与前三个点相连。你现在应该有四个点和六条线。跳到100个点,你将有4950条线或相互联系。每增加一个新的点,连接点与点之间的线的数量就会急剧增加。这是一个很基本简单的数学问题。

这里的复杂之处不在于这些点,而在于每增加一个点就会增加链接这些点的线的数量。如果你想到软件中的实体(类、对象实例、模块、组件、数据库、表等等),你也会很容易的觉察到,随着实体数量的增加,系统的复杂性也在增加。

虽然说软件里的这些实体并不是所有的之间都有联系。但你能肯定的说任何一个实体的变化都不会对其它实体产生影响吗?如果你有数百甚至数千个实体,那会发生什么?那将会远远超过任何人的实际能理解的数量,那时你还会确定你理解所有直接的相互作用吗?

那所有实体的整体效应又是如何呢?“如果”系统没有进行合适的“关注隔离”并且没有通过良好命名的“自解释的文档”这样的优良设计,从而导致每个实体的功能不是那么清晰怎么办?“如果”可以无限地添加,并且它们会随着你添加的实体的数量而增加。这些“如果”在奥卡姆剃刀原理的观点中就代表着“假设”,假设越多,你的系统就越复杂,因此风险就越高,失败的概率也就越大。

假设是伪装成已知的未知”,它代表了一种对系统完整性以及项目的成功来说隐藏的、非常真实的危险。

假设是生活中必不可少的一部分。假设帮助我们把生活的复杂性打包成漂亮整洁的小包裹,帮助我们管理每天每分钟都必须处理的大量信息。

假设是非常有用的,但不正确的假设会产生灾难性的影响。显然,我们无法测试每一个假设,这也就是经验无法替代的地方。

显然,复杂性必须要降低,假设必须被挑战!但如何做呢?这就是艺术之所在。如果你看看建筑(architecture)领域,你会发现它与软件的世界有很多相似之处。这两个领域都非常的具有技术性。在两个领域中简单性和优雅以及人类与结果交互的便利性是成功的关键因素,并且在这两个领域中,有许多方法和形式可以提供解决方案,所有这些方案都是为了满足需求。在这些方案中有些解决方案显然优于其他解决方案。在建筑中,“艺术”的成果通常更加明显且非常清晰可见,因为它们都表现在外观上。

伟大软件中灵感、直觉或远见不亚于伟大建筑上的灵感、直觉和远见。但在软件中并不是那么明显。一个伟大软件的解决方案应该是简单、优雅并且使用起来愉快的

这两个领域进行策划和设计的人都被称为架构师,这绝非巧合。在这两个领域,辉煌的成功都需要独一无二的人才。

许许多多的架构师中,他们的教育和工作背景也是多种多样的。但是优秀的架构师都有一个共同的特点是:他们会毫不留情的问“为什么”他们质疑设计的关键假设,为假设的存在和功能寻找确凿的理由。

优秀建筑架构师和优秀的软件架构师都会对设计中的每件事都有充分的理由。每个元素的原因都将有充分的理由,并且可以简单地解释。

如果一个实体的存在和它的功能不能简单地解释,那么很可能就像街道尽头的那个女人因为她是女巫的假设而被推理有罪一样,你的设计可能会受到过多假设的影响。

在很多时候,通过问“为什么”你会发现,很多需求不是以需求的形式展现出来,而是以解决方案的形式展现出来。通过多问“为什么”可以消除多层的假设,让你找到真实的需求,这个需求和被最初陈述的样子大不相同。(比如说,客户需求是“速度更快”,但是却以“马车”这样的解决方案来展现)

具有明确存在目的的实体在大型设计中往往能很好的融合在一起,因为没有重复有助于实现更简单、更优雅的设计。我们需要使用奥卡姆剃刀原理无情的去除不必要的实体,并制定简单、优雅、易于解释且不包含假设的设计。

相关原则

简单性原则

1、KISS:Keep it simple, stupid。保持简单,愚蠢。

KISS原则是软件设计中的最古老的原则之一。KISS 原则指出,大多数系统在保持简单而不是复杂的情况下工作得最好; 因此,简单应该是设计的一个关键目标,应该避免不必要的复杂性。软件系统必须由能力有限的人类开发人员维护,因此系统复杂性的任何增加也会增加维护它的难度。

2、YAGNI:You Aren’t Gonna Need It。你不会需要它。

这是一项来自于极限编程的原则,该原则指出:除非确实需要,否则程序员不应添加功能。

3、Last Responsible Moment:最后响应时刻。

尽可能晚做决定:尽可能推迟决定,直到可以根据事实而不是不确定的假设和预测做出决定。

4、复杂设计

当没有遵循简单性的原则,我们所得到的软件将有如下形式的复杂性:

4.1 不需要的特性

功能蠕变(Feature Creep):在产品中不断扩展或添加新功能过程中, 额外的功能超出了产品的基本功能,因此可能导致过度复杂而不是简单的设计。功能蠕变在软件系统中尤其常见,在软件系统中,添加原设计中不包含的新功能相对容易。这种特性扩展的结果之一就是众所周知的软件膨胀。

软件膨胀(Software Bloat):计算机程序的后续版本明显变慢,使用更多的内存或处理能力,或比前一个版本有更高的硬件要求的过程,同时只做了可疑的用户可感知的改进。

4.2 过度工程化

将产品设计得比其应用所需的更健壮或更复杂。过度工程的一个典型例子是有太多的抽象层。

5、过度简单设计

把复杂的问题和问题看得比实际简单得多。简单的软件设计可能只关注当前的功能需求,而忽略了某些非功能需求,如可维护性、可扩展性和可重用性。

相关名言

1、Everything should be made as simple as possible, but not simpler. – Albert Einstein

一切都应该尽可能简单,但不能更简单。

2、The business schools reward difficult complex behaviour more than simple behaviour, but simple behaviour is more effective. –Warren Buffett

商学院奖励困难的复杂行为多于简单行为,但简单行为更有效。

3、They say the world has become too complex for simple answers. They are wrong. – Ronald Reagan

他们说世界已经变得太复杂了,无法找到简单的答案。他们错了。

4、Simple can be harder than complex. You have to work hard to get your thinking clean to make it simple. - Steve Jobs

简单可能比复杂更难。你必须努力让你的思维变得干净,才能让它变得简单。

5、There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies. – C.A.R. Hoare

有两种构建软件设计的方法。一种方法是使其简单到显然没有缺陷。另一种方法是使它变得非常复杂,以至于没有明显的缺陷。

6、Always implement things when you actually need them, never when you just foresee that you need them. – Ron Jeffries

总是实现你真正需要的功能,绝不实现仅仅是预料所需要的功能。

参考资料:

https://naveenkumarmuguda.medium.com/occams-razor-in-software-development-56ee3e8b8ce8

https://www.cirdangroup.com/cirdan-blog/occams-razor-in-software-development

https://michaellant.com/2010/08/10/occams-razor-and-the-art-of-software-design/

https://effectivesoftwaredesign.com/2013/08/05/simplicity-in-software-design-kiss-yagni-and-occams-razor/