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

问题描述

自从去年我开始学习F#和OCaml以来,我读了大量文章,坚持认为设计模式(特别是Java)是强制语言中缺少的功能的解决方法。我发现一篇文章:

功能编程的主要功能包括作为一流价值,currying,不可变值等等。对于我来说,OO设计模式似乎是近似于任何这些功能似乎并不明显。



此外,在支持OOP的功能语言(如F#和OCaml),对我来说,使用这些语言的程序员会使用与其他OOP语言相同的设计模式。事实上,现在我每天都使用F#和OCaml,而且我在这些语言中使用的模式与使用Java编写的模式之间没有明显的区别。



声明功能编程是否消除了对OOP设计模式的需求,是否有道理?如果是这样,你可以发布或链接到一个典型的OOP设计模式和功能等同的例子?

解决方案

你引用夸大了它的声明。 FP不消除设计模式的需要。术语设计模式在FP语言中并没有广泛用于描述相同的东西。但它们存在。功能语言有很多最好的练习规则,形式当你遇到问题X,使用看起来像Y的代码,这基本上是一个设计模式。



然而,大多数特定于OOP的设计模式在功能语言中几乎没有任何关系是正确的。



我认为设计模式不应该是特别有争议的,一般来说,em>只存在来弥补语言的缺点。
如果另一种语言可以简单地解决相同的问题,那么其他语言就不需要设计模式了。该语言的用户可能甚至不知道问题存在,因为这样,这不是该语言的问题。



这里是四人帮不了解这个问题:

(以上是设计模式简介第4页第3段的引用)

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



所以是的,几个GoF设计模式被渲染冗余的FP语言,因为更强大和更容易使用的替代方案存在。



但是,当然还有设计模式是不解决的FP语言。单身人士的FP相当于什么? (忽略一下,单身一般是一个可怕的模式)



它也有两种方式。正如我所说,FP也有它的设计模式,人们通常都不会这样想。



但是你可能跑过单子。它们是什么,如果不是处理全球国家的设计模式呢?
这是一个在OOP语言中非常简单的问题,没有相应的设计模式存在。



我们不需要一个设计模式来增加一个静态变量或从该套接字读取,因为它只是您



在(纯)功能语言中,副作用和可变状态是不可能的,除非你使用monad设计模式或任何其他方法来允许同样的事情。

也许是因为你还在思考?很多人在处理强制性语言之后,在尝试功能语言时很难放弃这种习惯。 (我在F#看到一些非常有趣的尝试,其中字面上每个函数只是一串'let'语句,基本上就好像你采用了C程序一样,用'但是另一种可能性可能是你根本就没有意识到你正在简单地解决问题,这将需要OOP语言中的设计模式。



当您使用currying或将函数作为参数传递给另一个参数时,请停止并考虑如何以OOP语言执行此操作。

是的。 :)
当您使用FP语言时,您不再需要特定于OOP的设计模式。但是,您仍然需要一些一般的设计模式,如MVC或其他非OOP特定的东西,您需要几个新的FP特定的设计模式。所有语言都有缺点,而设计模式通常是我们如何解决问题。



无论如何,您可能会发现有趣的是以更清洁的FP语言来尝试,像ML(我个人最喜欢的,至少是为了学习目的),或者Haskell,当你面对新的东西时,你没有OOP拐杖回来。






如预期的那样,有些人反对将我的设计模式定义为修补语言的缺点,所以这里是我的理由:
如上所述大多数设计模式都是针对一种编程范式,有时甚至是一种特定语言。通常,它们解决了在该范例中仅存在的问题(请参阅FP的单引号或OOP的抽象工厂)。
为什么FP中不存在抽象工厂模式?因为它试图解决的问题不存在。
所以,如果在OOP语言中存在问题,这在FP语言中是不存在的,那么清楚地是OOP语言的缺点。这个问题可以解决,但你的语言并没有这样做,而是需要一堆你的代码来解决问题。理想情况下,我们希望我们的编程语言能够让所有的问题消失。任何仍然存在的问题原则上都是语言的缺陷。 ;)


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:

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.

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.

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?

解决方案

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.

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:

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

What is the command pattern, if not an approximation of first-class functions? :)In a 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.

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

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)

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.

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.

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.

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

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.

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.

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.

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: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).Why doesn't the abstract factory pattern exist in 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. 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设计模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 12:02