本文介绍了函数式编程会取代 GoF 设计模式吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自从我开始学习F#OCaml 去年,我阅读了大量文章,这些文章坚持认为设计模式(尤其是在 Java 中)是缺失功能的解决方法在命令式语言中.我发现的一篇文章提出了相当有力的主张:

Since I started learning F# and OCaml last year, I've read a huge number of articles which insist that design patterns (especially in Java) are workarounds for the missing features in imperative languages. One article I found makes a fairly strong claim:

我见过的大多数人都读过《设计模式》一书 by the Gang of四(GoF).任何自尊的程序员会告诉你这本书是语言不可知论和模式适用于软件工程一般,无论哪种语言你用.这是一个崇高的主张.不幸的是它远离真相.

函数式语言极其表现力.函数式语言一个不需要设计模式因为语言可能太高了水平,你最终编程消除设计的概念模式一起.

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) 的主要特性包括将函数作为一等值、柯里化、不可变值等.在我看来,OO 设计模式并没有接近这些特性中的任何一个.

The main features of functional programming (FP) 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.

此外,在支持 OOP 的函数式语言(例如 F# 和 OCaml)中,在我看来很明显,使用这些语言的程序员将使用与其他所有 OOP 语言都可用的相同设计模式.事实上,现在我每天都在使用 F# 和 OCaml,我在这些语言中使用的模式与我在 Java 中使用的模式之间没有显着差异.

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. In fact, right now I use F# and OCaml every day, and there are no striking differences between the patterns I use in these languages vs. the patterns I use when I write in Java.

关于函数式编程消除了对 OOP 设计模式的需要的说法是否有道理?如果是这样,您能否发布或链接到典型 OOP 设计模式及其等效功能的示例?

Is there any truth to the claim that functional programming eliminates the need for OOP design patterns? If so, could you post or link to an example of a typical OOP design pattern and its functional equivalent?

推荐答案

您引用的博客文章夸大了它的主张.FP 不会消除对设计模式的需求.术语设计模式"并未广泛用于描述 FP 语言中的相同事物.但它们存在.函数式语言有很多最佳实践规则,形式为当你遇到问题 X 时,使用看起来像 Y 的代码",这基本上就是设计模式.

The blog post you quoted overstates its claim a bit. FP doesn't eliminate the need for design patterns. The term "design patterns" just isn't widely used to describe the same thing in FP languages. 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.

然而,大多数 OOP 特定的设计模式与函数式语言几乎无关,这是正确的.

However, it's correct that most OOP-specific design patterns are pretty much irrelevant in functional languages.

我不认为说设计模式一般只是为了弥补语言中的缺点而存在的,这不应该引起特别的争议.如果另一种语言可以轻松解决相同的问题,那么这种语言就不需要设计模式了.使用该语言的用户甚至可能没有意识到问题存在,因为,这不是该语言的问题.

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:

编程语言的选择很重要,因为它会影响一个人的观点.我们的模式假设 Smalltalk/C++ 级别的语言特性,而这种选择决定了哪些可以轻松实现,哪些不能轻松实现.如果我们假设使用过程语言,我们可能会包含称为继承"、封装"和多态"的设计模式.同样,我们的一些模式直接由不太常见的面向对象语言支持.例如,CLOS 具有多种方法,从而减少了对诸如访问者之类的模式的需求.事实上,Smalltalk 和 C++ 之间存在足够多的差异,这意味着某些模式可以用一种语言比另一种语言更容易表达.(例如,参见迭代器.)

(以上引自《设计模式简介》一书,第 4 页,第 3 段)

(The above is a quote from the Introduction to the Design Patterns book, page 4, paragraph 3)

函数式的主要特点编程包括以下功能一流的价值观,柯里化,不可变值等.它似乎没有对我来说很明显 OO 设计模式正在接近其中的任何一个功能.

如果不是一等函数的近似值,命令模式是什么?:)在 FP 语言中,您只需将一个函数作为参数传递给另一个函数.在 OOP 语言中,您必须将函数封装在一个类中,您可以实例化该类,然后将该对象传递给另一个函数.效果是一样的,但在 OOP 中它被称为设计模式,它需要更多的代码.如果不是柯里化,抽象工厂模式是什么?每次给一个函数传递一点参数,配置它最终调用时会吐出什么样的值.

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.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. The effect is the same, but in OOP it's called a design pattern, and it takes a whole lot more code.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.

是的,在 FP 语言中,一些 GoF 设计模式变得多余,因为存在更强大且更易于使用的替代方案.

So yes, several GoF design patterns are rendered redundant in FP languages, because more powerful and easier to use alternatives exist.

当然还有一些设计模式不能被 FP 语言解决.什么是单例的 FP 等价物?(暂时忽略单身人士通常是一种糟糕的使用模式.)

But of course there are still design patterns which are not solved by FP languages. What is the FP equivalent of a singleton? (Disregarding for a moment that singletons are generally a terrible pattern to use.)

它也是双向的.正如我所说,FP 也有它的设计模式;人们只是通常不这么认为.

And it works both ways too. As I said, FP has its design patterns too; people just don't usually think of them as such.

但是您可能遇到过 monad.如果不是处理全局状态"的设计模式,它们是什么?这是一个在 OOP 语言中非常简单的问题,以至于那里不存在等效的设计模式.

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.

我们不需要增加静态变量"或从套接字读取"的设计模式,因为这正是您做的.

We don't need a design pattern for "increment a static variable", or "read from that socket", because it's just what you do.

说 monad 是一种设计模式,就像说带有通常操作的整数和零元素是一种设计模式一样荒谬.不,monad 是一种数学模式,而不是一种设计模式.

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.

此外,在函数式语言中支持 OOP(例如 F# 和OCaml),对我来说很明显使用这些语言的程序员将使用相同的设计模式发现可用于所有其他 OOP语.事实上,现在我使用 F#和 OCaml 每天,并且没有之间的显着差异我在这些语言中使用的模式 vs我在写作时使用的模式

也许是因为你还在急切地思考?很多人在用了一生的命令式语言之后,在尝试函数式语言时很难放弃这种习惯.(我在 F# 中看到过一些非常有趣的尝试,其中 每个 函数实际上只是一串let"语句,基本上就像您编写了一个 C 程序,并用 ' 替换了所有分号让'.:))

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'. :))

但另一种可能是,您只是没有意识到您正在解决的问题很琐碎,而这需要 OOP 语言中的设计模式.

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.

这样的说法有道理吗函数式编程消除了需要 OOP 设计模式吗?

是的.:)当您使用 FP 语言工作时,您不再需要特定于 OOP 的设计模式.但是您仍然需要一些通用的设计模式,例如 MVC 或其他非 OOP 特定的东西,并且您需要一些新的特定于 FP 的设计模式".所有语言都有其缺点,而设计模式通常是我们解决它们的方法.

Yep. :)When you work in a FP language, you no longer need the OOP-specific design patterns. 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. All languages have their shortcomings, and design patterns are usually how we work around them.

无论如何,您可能会发现尝试更干净"的 FP 语言很有趣,例如 ML(我个人最喜欢的,至少出于学习目的),或 Haskell,当您面对新事物时,您没有 OOP 支持.

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.

正如预期的那样,一些人反对我将设计模式定义为修补语言中的缺点",所以这是我的理由:

As expected, a few people objected to my definition of design patterns as "patching up shortcomings in a language", so here's my justification:

如前所述,大多数设计模式都特定于一种编程范式,有时甚至是一种特定语言.通常,它们解决的问题仅存在在该范式中(参见 FP 的 monad,或 OOP 的抽象工厂).

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中不存在抽象工厂模式?因为它试图解决的问题并不存在.

Why doesn't the abstract factory pattern exist in FP? Because the problem it tries to solve does not exist there.

所以,如果OOP语言存在问题,而FP语言不存在,那么显然这是OOP语言的一个缺点.问题可以解决,但您的语言不这样做,而是需要您提供一堆样板代码来解决它.理想情况下,我们希望我们的编程语言能够神奇地解决所有问题.任何仍然存在的问题原则上都是语言的缺点.;)

So, if a problem exists in OOP languages, which does not exist in FP languages, then clearly that is a shortcoming of OOP languages. 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. ;)

这篇关于函数式编程会取代 GoF 设计模式吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-27 17:48
查看更多