这篇引用的博客有点夸大其词。FP并没有消除对设计模式的需求,只是在FP语言中,“设计模式”这个术语不常被用来描述相同的事情。但是它们确实存在。函数式语言有很多最佳实践规则,形式为“当遇到问题X时,请使用看起来像Y的代码”,这基本上就是一个设计模式。
然而,大多数面向对象编程(OOP)特定的设计模式在函数式语言中几乎没有什么相关性。
总体而言,我认为可以说,设计模式存在的原因只是为了弥补语言的不足之处。如果另一种语言可以轻松地解决同样的问题,那么这种语言就不需要设计模式。该语言的用户甚至可能不知道该问题的存在,因为在该语言中,这不是一个问题。
以下是Gang of Four在这个问题上的观点:
选择编程语言很重要,因为它会影响人们的观点。我们的设计模式假设Smalltalk/C++级别的语言特性,并且这种选择决定了什么可以轻松地实现,什么无法轻松地实现。如果我们假设过程式语言,我们可能已经包括名为“Inheritance”、“Encapsulation”和“Polymorphism”的设计模式。同样,有些模式在不太常见的面向对象语言中直接支持。例如,CLOS具有多方法,这减少了像Visitor这样的模式的需要。实际上,在Smalltalk和C++之间存在足够的差异,以至于某些模式可以在一种语言中更容易地表达,而在另一种语言中则更难。(例如,参见Iterator)。
(以上是《设计模式》一书引言第4页第3段的引用)
函数式编程的主要特点包括函数作为一等公民、柯里化、不可变值等。对我来说,面向对象的设计模式似乎没有逼近这些特征。
如果不是函数式编程语言中的第一类函数的近似,那么命令模式是什么呢?在FP语言中,你只需将一个函数作为参数传递给另一个函数。在OOP语言中,您必须将函数封装在一个类中,然后实例化该对象,然后将该对象传递给其他函数。效果是相同的,但在面向对象编程中,它被称为设计模式,并且需要更多的代码。抽象工厂模式又是什么,如果不是柯里化?逐步向函数传递参数,以配置最终调用时它会产生什么样的值。
因此,几个GoF设计模式在FP语言中变得不再需要,因为存在更强大且易于使用的替代方法。但当然,仍然有一些设计模式在FP语言中没有被解决。例如,单例(Singleton)的FP等效项是什么?它也是双向的。正如我所说,函数式编程也有其设计模式;只是人们通常不会考虑它们。
但你可能已经遇到过单子。如果不是为了“处理全局状态”的设计模式,那么它们是什么?在面向对象的语言中,这是一个非常简单的问题,因此在那里不存在等效的设计模式。
我们不需要“增加静态变量”或“从该套接字读取”等设计模式,因为这就是你所做的。
认为单子是一个设计模式就像认为整数带有它们的普通操作和零元素一样荒谬。不,单子是一种数学模式,而不是设计模式。
在(纯)函数式语言中,除非你使用单子“设计模式”或其他允许相同操作的方法,否则不可能存在副作用和可变状态。
此外,在支持面向对象的函数式语言中(例如F#和OCaml),我认为使用这些语言的程序员将使用与任何其他面向对象语言中可用的相同的设计模式。实际上,现在我每天都使用F#和OCaml,并且在这些语言中使用的模式与我在Java中编写时使用的模式没有显着区别。
也许是因为你仍然在以命令式方式思考?很多人在一生中都使用命令式语言,当他们尝试使用函数式语言时,很难放弃这个习惯。(我见过一些非常有趣的F#尝试,其中每个函数基本上都是'let'语句的字符串。 :))
但另一个可能性是你还没有意识到在面向对象的语言中需要设计模式的那些微不足道的问题,在函数式语言中可以轻松解决。
当你使用了柯里化或将一个函数作为参数传递时,请停下来思考如何在面向对象的语言中完成它。
是的。当你使用FP语言工作时,你不再需要特定于OOP的设计模式。但是您仍然需要一些通用设计模式,例如MVC或其他非OOP特定内容,并且需要一些新的FP特定“设计模式”。所有语言都有其缺点,而设计模式通常是我们解决这些缺点的方法。
无论如何,你可能会发现尝试使用“更干净”的FP语言非常有趣,例如ML(至少在学习目的上是我个人最喜欢的)或Haskell,在这些语言中,当你面临新问题时,没有OOP支撑可以依靠。
正如预期的那样,一些人反对我的设计模式定义为“弥补语言缺陷”,因此这里是我的辩解:
正如已经说过的,大多数设计模式都特定于一种编程范型,有时甚至只限于一种具体语言。通常,它们解决了仅存在于该范型(请参见FP的monads或OOP的抽象工厂)中的问题。
为什么抽象工厂模式在FP中不存在?因为它试图解决的问题在那里并不存在。
因此,如果一个问题存在于OOP语言中,而在FP语言中不存在,那么显然这是OOP语言的缺陷。该问题可以得到解决,但您的语言并没有这样做,而需要您提供大量样板代码来解决它。理想情况下,我们希望编程语言可以神奇地消除所有问题。任何仍然存在的问题从本质上讲都是语言的缺陷。;)