Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 函数式编程与面向对象编程_Oop_Functional Programming_Paradigms - Fatal编程技术网

Oop 函数式编程与面向对象编程

Oop 函数式编程与面向对象编程,oop,functional-programming,paradigms,Oop,Functional Programming,Paradigms,到目前为止,我主要接触OO编程,并期待着学习一门函数式语言。我的问题是: 什么时候你会选择函数式编程而不是面向对象编程 函数式编程是一个更好的选择的典型问题定义是什么 您不必在这两种范式之间进行选择。您可以使用许多功能概念编写具有OO体系结构的软件FP和OOP本质上是正交的 以C#为例。你可以说它主要是OOP,但是有很多FP概念和构造。如果考虑 LINQ,允许LINQ存在的最重要的结构在本质上是功能性的: lambda表达式< /强> 另一个例子,F#。你可以说它主要是FP,但是有很多OOP

到目前为止,我主要接触OO编程,并期待着学习一门函数式语言。我的问题是:

  • 什么时候你会选择函数式编程而不是面向对象编程
  • 函数式编程是一个更好的选择的典型问题定义是什么

您不必在这两种范式之间进行选择。您可以使用许多功能概念编写具有OO体系结构的软件FP和OOP本质上是正交的

以C#为例。你可以说它主要是OOP,但是有很多FP概念和构造。如果考虑<强> LINQ,允许LINQ存在的最重要的结构在本质上是功能性的:<强> lambda表达式< /强>

另一个例子,F#。你可以说它主要是FP,但是有很多OOP概念和结构可用。您可以定义类、抽象类、接口,处理继承。甚至可以在使代码更清晰或显著提高性能时使用可变性

许多现代语言是多范式的

推荐阅读资料 由于我的处境相同(OOP背景,学习FP),我建议您阅读一些我非常欣赏的阅读材料:

  • ,杰里米·米勒著。这是一篇很棒的文章(尽管格式很差),展示了C#上的许多FP技术和实际示例

  • ,作者:托马斯·佩特里切克。这是一本主要讨论FP概念的好书,试图解释它们是什么,何时应该使用它们。F和C中都有很多例子。同时,它也是一个很好的信息来源

  • 如果您处于一个高度并发的环境中,那么纯函数式编程非常有用。由于缺少可变状态,并发几乎变得微不足道。见二郎

  • 在多模式语言中,如果可变状态的存在必须是一个实现细节,那么您可能希望从功能上对某些事情进行建模,因此FP是问题域的一个好模型。例如,请参见Python或D编程语言中的列表理解。它们的灵感来自函数式编程

  • 什么时候你会选择函数式编程而不是面向对象编程

    当您预期一种不同的软件发展时:

    • 当您对事物有一组固定的操作,并且随着代码的发展,您主要添加新事物时,面向对象语言是很好的。这可以通过添加实现现有方法的新类来实现,而现有的类则不受影响

    • 当您有一组固定的东西,并且随着代码的发展,您主要在现有的东西上添加新的操作时,函数式语言是很好的。这可以通过添加使用现有数据类型进行计算的新函数来实现,而现有函数则不受影响

    当进化走错方向时,你会遇到问题:

    • 向面向对象程序添加新操作可能需要编辑许多类定义才能添加新方法

    • 向功能程序中添加新类型的内容可能需要编辑许多功能定义以添加新案例

    这个问题已经众所周知很多年了;1998年。尽管一些研究人员认为表达问题可以通过诸如mixin之类的语言特性来解决,但一个被广泛接受的解决方案尚未进入主流

    函数式编程是一个更好的选择的典型问题定义是什么


    函数式语言擅长以树的形式处理符号数据。一个典型的例子是编译器,源语言和中间语言很少发生变化(大部分是相同的),但编译器编写者总是添加新的翻译和代码改进或优化(对事物的新操作)。编译和翻译通常是函数式语言的“杀手级应用程序”。

    面向对象编程提供:

  • 封装
    • 内部状态的控制突变
    • 限制耦合到内部表示
  • 子类型,允许:
    • 兼容类型的替换(多态性)
    • 在类之间共享实现的粗略方法(实现继承)
  • Haskell甚至Scala中的函数式编程可以通过更通用的类型类机制进行替换。不鼓励或禁止可变内部状态。也可以实现内部表示的封装。请参阅以获得良好的比较

    诺曼断言“向函数程序中添加一种新的东西可能需要编辑许多函数定义来添加一个新的案例。”这取决于函数代码使用类型类的程度。如果特定抽象数据类型上的模式匹配在整个代码库中传播,您确实会遇到这个问题,但从一开始它可能是一个糟糕的设计


    编辑删除了讨论类型类时对隐式转换的引用。在Scala中,类型类是用隐式参数编码的,而不是转换,尽管隐式转换是实现兼容类型替换的另一种方法。

    不要忘记,您可以将F和C代码混合在一起,这样您就可以充分利用每种代码的优点。您的答案是.Net强大功能的一个很好的例子。这表明它能够利用这两种范式的力量。嘿,如果我开始燃烧,对不起。我并不是说其他平台的功能不那么强大,只是说.NET不仅支持OOP。例如,它有尾部调用优化,我不认为FP和OOP是正交的。使用函数构造与函数编程不同。当然,在Linq中使用像lambdas这样的函数结构可以减少OO,但它仍然不是函数程序