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


当前回答

坚持住。

听到我声称已经取代了设计模式并揭穿了SOLID and DRY,许多人会更加恼怒。我没有人。尽管如此,我还是正确地建模了协作(制造)架构,并在我的网站http://www.powersemantics.com/上在线发布了构建过程的规则以及背后的代码和科学。

My argument is that design patterns attempt to achieve what manufacturing calls "mass customization", a process form in which every step can be reshaped, recomposed and extended. You might think of such processes as uncompiled scripts. I'm not going to repeat my (online) argument here. In short, my mass customization architecture replaces design patterns by achieving that flexibility without any of the messy semantics. I was surprised my model worked so well, but the way programmers write code simply doesn't hold a candle to how manufacturing organizes collaborative work.

制造=每个步骤都与一个产品相互作用 OOP =每个步骤都与自身和其他模块交互,像无用的上班族一样将产品从一点传递到另一点

这种架构永远不需要重构。还有一些关于中心化和分布式的规则会影响复杂性。但为了回答你的问题,函数式编程是另一组处理语义,而不是用于大规模定制流程的体系结构,其中1)源路由作为(脚本)文档存在,使用者可以在触发之前重写,2)模块可以轻松动态地添加或删除。

我们可以说OOP是“硬编码过程”范式,而设计模式是避免这种范式的方法。但这就是大规模定制。设计模式将动态过程体现为混乱的硬代码。没有任何意义。f#允许将函数作为参数传递,这意味着函数式语言和面向对象语言都试图自己完成大规模定制。

代表脚本的硬代码会让读者感到困惑吗?如果你认为你的编译器的消费者为这些特性买单,那就完全不是,但对我来说,这些特性是语义上的浪费。它们是毫无意义的,因为大规模定制的重点是使过程本身是动态的,而不仅仅是对使用Visual Studio的程序员是动态的。

其他回答

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

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

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

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

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

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

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

模式是解决类似问题的方法,这些问题会一次又一次地出现,然后被描述和记录。所以不,FP不会取代模式;然而,FP可能会创建新的模式,并使一些当前的“最佳实践”模式“过时”。

坚持住。

听到我声称已经取代了设计模式并揭穿了SOLID and DRY,许多人会更加恼怒。我没有人。尽管如此,我还是正确地建模了协作(制造)架构,并在我的网站http://www.powersemantics.com/上在线发布了构建过程的规则以及背后的代码和科学。

My argument is that design patterns attempt to achieve what manufacturing calls "mass customization", a process form in which every step can be reshaped, recomposed and extended. You might think of such processes as uncompiled scripts. I'm not going to repeat my (online) argument here. In short, my mass customization architecture replaces design patterns by achieving that flexibility without any of the messy semantics. I was surprised my model worked so well, but the way programmers write code simply doesn't hold a candle to how manufacturing organizes collaborative work.

制造=每个步骤都与一个产品相互作用 OOP =每个步骤都与自身和其他模块交互,像无用的上班族一样将产品从一点传递到另一点

这种架构永远不需要重构。还有一些关于中心化和分布式的规则会影响复杂性。但为了回答你的问题,函数式编程是另一组处理语义,而不是用于大规模定制流程的体系结构,其中1)源路由作为(脚本)文档存在,使用者可以在触发之前重写,2)模块可以轻松动态地添加或删除。

我们可以说OOP是“硬编码过程”范式,而设计模式是避免这种范式的方法。但这就是大规模定制。设计模式将动态过程体现为混乱的硬代码。没有任何意义。f#允许将函数作为参数传递,这意味着函数式语言和面向对象语言都试图自己完成大规模定制。

代表脚本的硬代码会让读者感到困惑吗?如果你认为你的编译器的消费者为这些特性买单,那就完全不是,但对我来说,这些特性是语义上的浪费。它们是毫无意义的,因为大规模定制的重点是使过程本身是动态的,而不仅仅是对使用Visual Studio的程序员是动态的。