The blog post you quoted overstates its claim a bit.
(您引用的博客文章夸大了其声明。)
FP doesn't eliminate the need for design patterns. (FP并没有消除对设计模式的需求。)
The term "design patterns" just isn't widely used to describe the same thing in FP languages. (术语“设计模式”只是没有被广泛用于在FP语言中描述同一件事。)
But they exist. (但是它们存在。)
Functional languages have plenty of best practice rules of the form "when you encounter problem X, use code that looks like Y", which is basically what a design pattern is. (函数式语言具有许多最佳实践规则,其形式为“遇到问题X时,使用看起来像Y的代码”,这基本上就是一种设计模式。)
However, it's correct that most OOP-specific design patterns are pretty much irrelevant in functional languages.
(但是,正确的是,大多数特定于OOP的设计模式在功能语言中几乎无关紧要。)
I don't think it should be particularly controversial to say that design patterns in general only exist to patch up shortcomings in the language.
(我认为一般地说,仅存在设计模式是为了弥补该语言的不足,这并不是特别有争议。)
And if another language can solve the same problem trivially, that other language won't have need of a design pattern for it. (如果另一种语言可以轻松解决相同的问题,则该另一种语言将不需要设计模式。)
Users of that language may not even be aware that the problem exists , because, well, it's not a problem in that language. (使用该语言的用户甚至可能没有意识到问题的存在 ,因为,这不是该语言的问题。)
Here is what the Gang of Four has to say about this issue:
(这是“四人帮”对此问题的评价:)
The choice of programming language is important because it influences one's point of view.
(编程语言的选择很重要,因为它会影响一个人的观点。)
Our patterns assume Smalltalk/C++-level language features, and that choice determines what can and cannot be implemented easily. (我们的模式假定使用Smalltalk / C ++级别的语言功能,并且该选择确定了可以轻松实现的内容。)
If we assumed procedural languages, we might have included design patterns called "Inheritance", "Encapsulation," and "Polymorphism". (如果采用过程语言,则可能包括称为“继承”,“封装”和“多态”的设计模式。)
Similarly, some of our patterns are supported directly by the less common object-oriented languages. (同样,不太常见的面向对象语言直接支持我们的某些模式。)
CLOS has multi-methods, for example, which lessen the need for a pattern such as Visitor. (例如,CLOS具有多种方法,可以减少对访问者之类的模式的需求。)
In fact, there are enough differences between Smalltalk and C++ to mean that some patterns can be expressed more easily in one language than the other. (实际上,Smalltalk和C ++之间存在足够的差异,这意味着某些模式可以用一种语言比另一种语言更容易地表达。)
(See Iterator for example.) ((例如,请参见Iterator。))
(The above is a quote from the Introduction to the Design Patterns book, page 4, paragraph 3)
((以上引自《设计模式简介》书第4页第3段))
The main features of functional programming include functions as first-class values, currying, immutable values, etc. It doesn't seem obvious to me that OO design patterns are approximating any of those features.
(函数式编程的主要特征包括函数,例如一流的值,currying,不可变的值等。在我看来,OO设计模式无法近似所有这些功能。)
What is the command pattern, if not an approximation of first-class functions?
(命令模式是什么(如果不是一流函数的近似)?)
:) In an FP language, you'd simply pass a function as the argument to another function. (:)在FP语言中,您只需将一个函数作为参数传递给另一个函数。)
In an OOP language, you have to wrap up the function in a class, which you can instantiate and then pass that object to the other function. (在OOP语言中,必须将函数包装在一个类中,可以实例化该类,然后将该对象传递给另一个函数。)
The effect is the same, but in OOP it's called a design pattern, and it takes a whole lot more code. (效果是相同的,但是在OOP中,它称为设计模式,并且需要大量的代码。)
And what is the abstract factory pattern, if not currying? (如果不使用抽象工厂模式,那又是什么呢?)
Pass parameters to a function a bit at a time, to configure what kind of value it spits out when you finally call it. (一次将参数传递给一个函数,以配置在最终调用它时会吐出哪种值。)
So yes, several GoF design patterns are rendered redundant in FP languages, because more powerful and easier to use alternatives exist.
(因此,是的,由于存在更强大且更易于使用的替代方案,因此在FP语言中使多个GoF设计模式变得多余。)
But of course there are still design patterns which are not solved by FP languages.
(但是,当然,仍然有设计未通过FP语言解决模式。)
What is the FP equivalent of a singleton? (FP等于单身人士吗?)
(Disregarding for a moment that singletons are generally a terrible pattern to use.) ((暂时忽略单例通常是一个可怕的模式。))
And it works both ways too.
(而且它也双向起作用。)
As I said, FP has its design patterns too; (如我所说,FP也有其设计模式。)
people just don't usually think of them as such. (人们通常通常不会这样认为。)
But you may have run across monads.
(但是您可能遇到过单子。)
What are they, if not a design pattern for "dealing with global state"? (如果不是“应对全球状态”的设计模式,它们是什么?)
That's a problem that's so simple in OOP languages that no equivalent design pattern exists there. (这个问题在OOP语言中是如此简单,以至于那里没有等效的设计模式。)
We don't need a design pattern for "increment a static variable", or "read from that socket", because it's just what you do .
(我们不需要一个设计模式为“增加一个静态变量”,或“从套接字读取”,因为这是你怎么做 。)
Saying a monad is a design pattern is as absurd as saying the Integers with their usual operations and zero element is a design pattern.
(说单子是一种设计模式,就像说整数以其通常的操作和零元素是一种设计模式一样荒谬。)
No, a monad is a mathematical pattern , not a design pattern. (不,monad是数学模式 ,而不是设计模式。)
In (pure) functional languages, side effects and mutable state are impossible, unless you work around it with the monad "design pattern", or any of the other methods for allowing the same thing.
(在(纯)功能语言中,除非您使用monad“设计模式”或允许同一事物的任何其他方法来解决,否则副作用和可变状态是不可能的。)
Additionally, in functional languages which support OOP (such as F# and OCaml), it seems obvious to me that programmers using these languages would use the same design patterns found available to every other OOP language.
(此外,在支持OOP的功能语言(例如F#和OCaml)中,对我来说显而易见的是,使用这些语言的程序员将使用与其他OOP语言相同的设计模式。)
In fact, right now I use F# and OCaml everyday, and there are no striking differences between the patterns I use in these languages vs the patterns I use when I write in Java. (实际上,现在我每天都在使用F#和OCaml,并且在这些语言中使用的模式与用Java编写时使用的模式之间没有显着差异。)
Perhaps because you're still thinking imperatively?
(也许是因为您仍在进行必要的思考?)
A lot of people, after dealing with imperative languages all their lives, have a hard time giving up on that habit when they try a functional language. (许多人一生都在使用命令式语言,但是在尝试使用功能性语言时却很难放弃这种习惯。)
(I've seen some pretty funny attempts at F#, where literally every function was just a string of 'let' statements, basically as if you'd taken a C program, and replaced all semicolons with 'let'. :)) ((我在F#上看到了一些非常有趣的尝试,实际上每个函数只是一串'let'语句,基本上就像您使用了C程序一样,并用'let'替换了所有分号。:))
But another possibility might be that you just haven't realized that you're solving problems trivially which would require design patterns in an OOP language.
(但是另一种可能是,您可能还没有意识到自己正在琐碎地解决问题,而这需要使用OOP语言的设计模式。)
When you use currying, or pass a function as an argument to another, stop and think about how you'd do that in an OOP language.
(当您使用currying或将一个函数作为参数传递给另一个函数时,请停下来想一想如何使用OOP语言来实现。)
Is there any truth to the claim that functional programming eliminates the need for OOP design patterns?
(函数式编程消除了对OOP设计模式的需求,这有什么道理可言吗?)
Yep.
(是的)
:) When you work in a FP language, you no longer need the OOP-specific design patterns. (:)使用FP语言时,您不再需要特定于OOP的设计模式。)
But you still need some general design patterns, like MVC or other non-OOP specific stuff, and you need a couple of new FP-specific "design patterns" instead. (但是,您仍然需要一些常规的设计模式,例如MVC或其他非OOP特定的内容,并且需要几个新的FP特定的“设计模式”。)
All languages have their shortcomings, and design patterns are usually how we work around them. (所有语言都有其缺点,设计模式通常是我们解决它们的方法。)
Anyway, you may find it interesting to try your hand at "cleaner" FP languages, like ML (my personal favorite, at least for learning purposes), or Haskell , where you don't have the OOP crutch to fall back on when you're faced with something new.
(无论如何,您可能会发现尝试“更清洁”的FP语言很有趣,例如ML (我个人最喜欢的,至少出于学习目的)或Haskell ,当您没有OOP拐杖时面临着新的事物。)
As expected, a few people objected to my definition of design patterns as "patching up shortcomings in a language", so here's my justification:
(不出所料,一些人反对我对设计模式的定义为“弥补一种语言的缺陷”,所以这是我的理由:)
As already said, most design patterns are specific to one programming paradigm, or sometimes even one specific language.
(如前所述,大多数设计模式特定于一种编程范例,有时甚至特定于一种特定的语言。)
Often, they solve problems that only exist in that paradigm (see monads for FP, or abstract factories for OOP). (通常,它们可以解决仅存在于该范例中的问题(有关FP,请参见monad,有关OOP,请参见抽象工厂)。)
Why doesn't the abstract factory pattern exist in FP?
(为什么FP中不存在抽象工厂模式?)
Because the problem it tries to solve does not exist there. (因为它尝试解决的问题在那里不存在。)
So, if a problem exists in OOP languages, which does not exist in FP languages, then clearly that is a shortcoming of OOP languages.
(因此,如果OOP语言中存在问题,而FP语言中不存在问题,那么显然这是OOP语言的缺点。)
The problem can be solved, but your language does not do so, but requires a bunch of boilerplate code from you to work around it. (这个问题可以解决,但是您的语言却不能解决,但是您需要一堆样板代码来解决。)
Ideally, we'd like our programming language to magically make all problems go away. (理想情况下,我们希望我们的编程语言能够神奇地解决所有问题。)
Any problem that is still there is in principle a shortcoming of the language. (原则上仍然存在任何问题,这是该语言的缺点。)
;) (;))