函数式编程与面向对象编程
到目前为止,我主要面向OO编程,并期待学习一种function性语言。 我的问题是:
- 你什么时候select面向对象的函数式编程?
- 函数式编程是一个更好的select,典型的问题定义是什么?
你什么时候select面向对象的函数式编程?
当你预期一种不同types的软件演变时:
-
面向对象的语言对事物有一套固定的操作是很好的,随着代码的发展,你主要增加新的东西。 这可以通过添加实现现有方法的新类来实现,而现有的类则单独存在。
-
函数式语言当你有一套固定的东西的时候是很好的,随着你的代码的发展,你主要在现有的东西上添加新的操作 。 这可以通过添加用现有数据types进行计算的新function来完成,并且现有的function是独立的。
当进化错误的时候,你有问题:
-
将一个新的操作添加到面向对象的程序可能需要编辑许多类定义来添加一个新的方法。
-
为function程序添加新的function可能需要编辑许多function定义来添加新的function。
这个问题已经有很多年了, 1998年, 菲尔·瓦德勒把它称为“expression问题” 。 尽pipe一些研究者认为expression式问题可以用混合语言这样的语言特征来解决,但一个被广泛接受的解决scheme尚未成为主stream。
函数式编程是一个更好的select,典型的问题定义是什么?
函数式语言擅长以树forms操作符号数据。 一个最喜欢的例子是编译器,源代码和中间语言很less改变(大多数是相同的东西 ),但编译器编写者总是添加新的翻译和代码改进或优化(对事物的新操作)。 编译和翻译更一般地是function语言的“杀手级应用程序”。
你不一定必须在两种范例之间做出select。 您可以使用许多function概念编写具有OO体系结构的软件。 FP和OOP本质上是正交的 。
以C#为例。 你可以说这主要是OOP,但是有许多FP的概念和构造。 如果你考虑Linq ,允许Linq存在的最重要的构造本质上是function性的: lambdaexpression式 。
又如F#。 你可以说这主要是FP,但是有很多OOP的概念和结构可用。 你可以定义类,抽象类,接口,处理inheritance。 你甚至可以使用可变性,当你的代码更清晰,或者当它显着提高性能。
许多现代语言是多范式的。
推荐读物
因为我在同一条船(OOP背景,学习FP),所以我build议你阅读一些我非常感谢的内容:
-
日常.NET开发的函数式编程 ,作者:Jeremy Miller 一篇很棒的文章(虽然格式不佳)显示了许多C#上的FP技术和实际实例。
-
真实世界的function编程 ,Tomas Petricek。 一本很好的书,主要涉及FP概念,试图解释它们是什么,什么时候应该使用。 F#和C#中都有很多例子。 另外, Petricek的博客是一个很好的信息来源。
面向对象编程提供:
- 封装,以
- 控制内部状态的变异
- 限制耦合到内部表示
- 分类,允许:
- 兼容types的替代(多态性)
- 在类之间共享实现的粗糙方法(实现inheritance)
函数式编程,在Haskell中,甚至在Scala中,都可以通过types类的更一般的机制来进行replace。 可变的内部状态是不鼓励或禁止的。 也可以实现内部表示的封装。 看一下Haskell和OOP的比较。
诺曼的断言是:“为function程序添加新的function可能需要编辑许多function定义来添加新的function”。 取决于function代码采用的typestypes。 如果特定的抽象数据types上的模式匹配遍布在代码库中,那么确实会遇到这个问题,但这可能是一个糟糕的devise。
EDITED讨论types类时,删除对隐式转换的引用。 在Scala中,types类使用隐式参数编码,而不是转换,尽pipe隐式转换是实现兼容typesreplace的另一种方式。
-
如果你处于高度并发的环境中,那么纯粹的函数式编程是有用的。 缺乏可变状态使并发几乎微不足道。 见Erlang。
-
在多参数语言中,如果可变状态的存在必须是实现细节,那么可能需要在function上对一些事物build模,因此FP是问题域的良好模型。 例如,请参阅Python编程语言中的list comprehensions或D编程语言中的std.range 。 这些都是function编程的启发。
面向对象程序devise(OOP)是一种基于“对象”概念的编程范例,它是以字段的forms包含数据的数据结构,通常称为属性; 和程序的forms,通常被称为方法。
函数式编程是一种编程范式,是构build计算机程序结构和元素的一种风格,将计算视为math函数的评估,避免了变化状态和可变数据。
OOP表示,将数据及其行为集中到一个位置,可以更容易地理解程序是如何工作的。 FP说,数据和行为是截然不同的事情,为了清晰起见,应该分开保存。
即使将Javascript和面向对象编程相结合,开发人员也可以编写清晰,简洁和可重复的代码。 开发人员可以创build小块代码,然后可以再次调用,而不必重写代码或一遍又一遍地复制粘贴代码。 OOP JavaScript还提供了基于类的基于原型的inheritance,它允许对象直接从其他对象inheritance。