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

其他回答

坚持住。

听到我声称已经取代了设计模式并揭穿了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的程序员是动态的。

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

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

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

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.

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

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

函数式编程消除了对面向对象设计模式的需求这一说法是否属实?

函数式编程与面向对象编程不同。面向对象的设计模式不适用于函数式编程。取而代之的是函数式编程设计模式。

对于函数式编程,您不需要阅读面向对象设计模式书籍;你会读到其他关于FP设计模式的书籍。

语言无关的

不完全。对于面向对象语言,只有语言不可知。这种设计模式根本不适用于过程式语言。它们在关系数据库设计上下文中几乎没有意义。它们不适用于设计电子表格。

一个典型的OOP设计模式和它的功能对等物?

上述情况不应该存在。这就像要求将一段过程代码重写为OO代码。嗯……如果我将原始的Fortran(或C)翻译成Java,我所做的只是翻译它。如果我完全将其重写为面向对象范式,它将不再看起来像原始的Fortran或C语言——它将无法识别。

从面向对象设计到功能设计没有简单的映射。他们看问题的方式完全不同。

函数式编程(像所有编程风格一样)具有设计模式。关系数据库有设计模式,OO有设计模式,过程式编程有设计模式。任何事物都有设计模式,甚至是建筑物的结构。

设计模式——作为一个概念——是一种永恒的构建方式,与技术或问题领域无关。但是,特定的设计模式适用于特定的问题领域和技术。

每个人只要仔细思考自己在做什么,就会发现设计模式。