自从我去年开始学习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设计模式的例子及其功能对等物吗?


当前回答

GoF这本书明确地将自己与面向对象绑定在一起——书名是《设计模式——可重用面向对象软件的元素》(重点是我的)。

其他回答

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

Norvig的演示暗示了他们对所有GoF模式的分析,他们说23个模式中有16个在函数式语言中有更简单的实现,或者只是语言的一部分。因此,大概至少有7个要么是a)同样复杂,要么是b)没有出现在语言中。不幸的是,我们没有列举它们!

我认为很明显,GoF中的大多数“创造性”或“结构性”模式只是让Java或c++中的原始类型系统做你想做的事情的技巧。但是不管你用什么语言编程,其余的都是值得考虑的。

一个可能是Prototype;虽然它是JavaScript的基本概念,但它必须在其他语言中从头开始实现。

我最喜欢的模式之一是空对象模式:表示一个对象不做任何适当的事情。这可能更容易在函数式语言中建模。然而,真正的成就是视角的转变。

GoF这本书明确地将自己与面向对象绑定在一起——书名是《设计模式——可重用面向对象软件的元素》(重点是我的)。

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

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

从本质上说,是的!

当一个模式绕过了缺失的特性(高阶函数、流处理……),最终促进了组合。 一遍又一遍地重写模式实现的需要本身可以被视为一种语言气味。

此外,这个页面(AreDesignPatternsMissingLanguageFeatures)提供了一个“模式/功能”转换表和一些不错的讨论,如果你愿意深入研究的话。