自从我去年开始学习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设计模式可以通过函数式编程进行修改,以简化设计并保持目的。

其他回答

恕我说一句,函数式编程最重要的特点是,你只用表达式来编程——表达式中的表达式,表达式中的表达式,所有的表达式都计算到最后,最终的表达式“计算时使机器变热”。

以我之见,面向对象编程的最重要的特征是,您正在使用具有内部状态的对象进行编程。在纯函数中不能有内部状态——面向对象的编程语言需要语句来实现。(函数式编程中没有语句。)

你是在拿苹果和橘子作比较。面向对象编程的模式不适用于函数编程,因为函数式编程是使用表达式进行编程,而面向对象编程是使用内部状态进行编程。

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

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

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

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

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

布莱恩关于语言和模式之间紧密联系的评论很中肯,

The missing part of this discussion is the concept of idiom. James O. Coplien's book, "Advanced C++" was a huge influence here. Long before he discovered Christopher Alexander and the Column Without a Name (and you can't talk sensibly about patterns without reading Alexander either), he talked about the importance of mastering idioms in truly learning a language. He used string copy in C as an example, while(*from++ = *to++); You can see this as a bandaid for a missing language feature (or library feature), but what really matters about it is that it's a larger unit of thought, or of expression, than any of its parts.

这就是模式和语言试图做的,让我们更简洁地表达我们的意图。思想的单位越丰富,你能表达的思想就越复杂。从系统架构到琐碎小事,在不同的范围内拥有丰富的、共享的词汇,可以让我们进行更明智的对话,并思考我们应该做什么。

作为个体,我们也可以学习。这就是练习的意义所在。我们每个人都能理解和使用我们自己永远无法想到的东西。语言、框架、库、模式、习语等等都在共享知识财富中占有一席之地。