OOP和FP的区别

18-11-29 banq
         

首先确定什么是OOP和什么是FP?

什么是OOP?

为了真正掌握这一理念,我强烈建议您关注Alan Kay的工作。当然,他并不是这种模式背后唯一的人,但我发现他的解释非常明确。这个主题演讲是一个良好的开端。简而言之,艾伦(除了其他知识)拥有生物学博士学位。复杂生物的工作方式基本上是启发OOP范式的原因。

换句话说:通过专门组件协作来实现复杂的任务。每个组件都可以是独立的,不需要了解整个系统。

他们只是合作,在需要某些消息时收到消息,并在他们为系统做了一些有意义的事情时发送消息。这些组件如何进行通信,以及如何管理它们之间的编排不是由范例强加的。不同的语言使用了不同的实现。但是这种独立组件协作的概念是OOP的核心概念。

什么是FP

函数编程不是在生物学领域寻找灵感,而是植根于数学。我将引用Philip Wadler给出一个更好的定义:

“ 纯函数式语言中的程序是作为一组方程式编写的。显式数据流确保表达式的值仅取决于其自由变量。因此,将等号一边替换为另外一边总是有效的,这使得这些程序特别易于推理。[...]显式数据流也确保计算顺序无关紧要,使[函数]程序容易受到惰性评估。“

他的意思是什么?如果我写X = A + B,或Y = C * DI不关心A和B,或C和D的值。这是一个数学方程,它代表了所有有效值的概念。类型A和B,或类型C和D的乘法。因此我可以用Y组成X,并做替换:X >> Y =(A + B)>> Y = X >>(C * D)=( A + B)>>(C * D)

(>>是F#中的合成运算符)

如果这些值中的任何一个有可能在我的范围之外改变(变异),那么所有这些推理都不再成立。更糟糕的是,如果不仅值,而且类型可以改变。这就是我们在FP中说的原因,我们可以编写只在本地逻辑有效的代码。我知道我的“方程式”(或纯函数)总是正确的,不需要考虑世界其他地方来确保这一点。

请注意,这种“本地思维”的意愿也可以在OOP的“独立组件”中找到。但与OOP相反,由于数学原因,FP解释了如何实现它。

哪一个是最好的?

最后,整个行业多年来一直在寻找答案。问题应该改为:在我的背景下哪一个是最好的?现在我们可以开始谈谈了。

您拥有的约束越多,编写的代码就越难,从长远来看维护代码就越容易。什么是代码约束?我们有许多取决于语言:语法,不变性,无副作用,单元测试,类型和依赖类型。

是否更快地编写代码或拥有长期可维护代码?在开始启动的时候,我可能需要快速生成代码,直到找到好的产品。在涉及活的变化的关键环境中,我可能想要一些强大的东西,即使我需要1年的时间来编写它。

当然,从“快速和肮脏”到“数学上强大”的所有尺度都可能取决于您的背景上下文。

只是工具

函数编程本质上比面向对象编程更受限制。因为它禁止可变性和副作用。当语言也使用类型时,它会产生强大的概念,如类型驱动开发,我们可以通过设计从系统中删除无效状态,使其在运行时更加健壮。当语言也使用依赖类型时,我们甚至可以将业务规则编码为类型,以避免在不满足业务规则时进行编译。缺点是:它难以编写。

但是当你完成函数的编写后,你可以相信这句名言“如果它能编译,它就很有效”。维护此代码通常比庞大的OO代码库更容易,因为由于纯函数,我们可以使用本地推理来维护系统。请注意我前一句中的“通常”。

​​​​​​​FP难以编写,但易于维护(更容易推理)。OOP更容易编写,但更难维护(由于副作用而难以推理)。