自从我去年开始学习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的书将其中一些正规化了。如果随着开发人员使用函数式编程语言而出现新的模式,那将是令人兴奋的事情,也许也会有关于它们的书籍。

其他回答

我认为每个范式都有不同的目的,因此不能以这种方式进行比较。

我还没有听说过GoF设计模式适用于每一种语言。我听说它们适用于所有面向对象语言。如果您使用函数式编程,那么您解决的问题领域就不同于OO语言。

我不会使用函数式语言来编写用户界面,但是像c#或Java这样的面向对象语言会使这项工作更容易。如果我正在编写一种函数式语言,那么我就不会考虑使用OO设计模式。

Peter Norvig的《动态编程中的设计模式》(Design Patterns in Dynamic Programming)对这一主题进行了深入的讨论,不过他讲的是“动态”语言而不是“函数式”语言(两者有重叠)。

有些模式更容易在支持FP的语言中实现。例如,策略可以很好地使用闭包来实现。然而,根据上下文,您可能更喜欢使用基于类的方法来实现策略,例如策略本身非常复杂和/或共享您想使用模板方法建模的结构。

根据我在多范式语言(Ruby)中开发的经验,FP实现在简单的情况下工作得很好,但是在上下文更复杂的情况下,基于GoF OOP的方法更适合。

FP方法并没有取代OOP方法,而是对其进行了补充。

我想引用Jeremy Gibbons的两篇优秀但有些密集的论文:《作为高阶数据类型泛型程序的设计模式》和《迭代器模式的精髓》(这两篇文章都可以在http://www.comlab.ox.ac.uk/jeremy.gibbons/publications/上找到)。

它们都描述了惯用函数构造如何覆盖其他(面向对象)设置中特定设计模式所覆盖的领域。

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