自从我去年开始学习f#和OCaml以来,我已经阅读了大量的文章,这些文章坚持认为设计模式(尤其是Java中的)是命令式语言中缺失特性的变通方法。我发现的一篇文章给出了相当有力的主张:

Most people I've met have read the Design Patterns book by the Gang of Four (GoF). Any self respecting programmer will tell you that the book is language agnostic and the patterns apply to software engineering in general, regardless of which language you use. This is a noble claim. Unfortunately it is far removed from the truth. Functional languages are extremely expressive. In a functional language one does not need design patterns because the language is likely so high level, you end up programming in concepts that eliminate design patterns all together.

函数式编程(FP)的主要特性包括函数作为一类值、curry化、不可变值等。在我看来,OO设计模式是否接近这些特性并不明显。

此外,在支持OOP的函数式语言(如f#和OCaml)中,使用这些语言的程序员显然会使用与其他OOP语言相同的设计模式。事实上,现在我每天都在使用f#和OCaml,我在这些语言中使用的模式与我在Java中使用的模式之间没有明显的区别。

函数式编程消除了对面向对象设计模式的需求这一说法是否属实?如果是这样的话,你能发布或链接到一个典型的OOP设计模式的例子及其功能对等物吗?


当前回答

我想说的是,当你拥有像Lisp这样支持宏的语言时,你就可以构建你自己的领域特定的抽象,这些抽象通常比一般的习语解决方案要好得多。

其他回答

在2013年的新书《函数式编程模式- In Scala and Clojure》中,作者Michael.B。Linn在很多情况下对GoF模式进行了比较和替换,并讨论了较新的功能模式,如“尾递归”、“记忆化”、“惰性序列”等。

这本书在亚马逊上有售。作为一个拥有几十年OO背景的人,我发现这本书内容丰富,令人鼓舞。

在函数式编程中,设计模式有不同的含义。事实上,大多数OOP设计模式在函数式编程中都是不必要的,因为有更高层次的抽象和hof用作构建块。

HOF的原理意味着函数可以作为 参数指向其他函数。函数可以返回值。

确实如此,因为高级函数式PL(如OCaml,带有类、模块等)在类型多功能性和表达能力方面肯定会取代OOP命令式语言。抽象不会泄露,你可以在程序中直接表达你的大部分想法。因此,是的,它确实取代了设计模式,无论如何,与功能模式相比,大多数设计模式都简单得可笑。

正如其他人所说,函数式编程有特定的模式。我认为摆脱设计模式的问题与其说是转换到功能的问题,不如说是语言特性的问题。

看看Scala是如何废除“单例模式”的:只需声明一个对象而不是一个类。 另一个特性,模式匹配,有助于避免笨重的访问者模式。对比如下: Scala的模式匹配=类固醇访问者模式

Scala和f#一样,是OO-functional的融合。我不了解f#,但它可能有这些特性。

闭包是在函数式语言中出现的,但不需要被限制在函数式语言中。它们有助于使用委托模式。

还有一个观察结果。这段代码实现了一个模式:它是如此经典,如此基本,以至于我们通常不认为它是一个“模式”,但它确实是:

for(int i = 0; i < myList.size(); i++) { doWhatever(myList.get(i)); }

像Java和c#这样的命令式语言已经采用了本质上是一个函数结构来处理这个问题:“foreach”。

我认为只有两个GoF设计模式是用来将函数式编程逻辑引入自然的面向对象语言的。我想到了《战略与指挥》。 其他一些GoF设计模式可以通过函数式编程进行修改,以简化设计并保持目的。