Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
静态方法使Java成为伪函数语言?_Java_Closures_Functional Programming - Fatal编程技术网

静态方法使Java成为伪函数语言?

静态方法使Java成为伪函数语言?,java,closures,functional-programming,Java,Closures,Functional Programming,我一直在思考Misko Hevery的一个观点,即Java中的静态方法是可测试性的致命武器。我不想讨论可测试性问题,而是更多地讨论静态方法的概念。为什么人们如此讨厌它 的确,我们没有闭包(但是我们有一个稍微笨拙的匿名函数),lambdas&函数作为第一类对象。在某种程度上,我认为静态方法可以用来将函数模拟为第一类对象 静态方法使测试变得困难,因为它们是不可替代的,就这么简单 静态方法如何“模拟”函数作为第一类对象1?可以说,在这方面,他们比任何其他人都糟糕。通过创建单个方法接口,您可以将函数“模

我一直在思考Misko Hevery的一个观点,即Java中的静态方法是可测试性的致命武器。我不想讨论可测试性问题,而是更多地讨论静态方法的概念。为什么人们如此讨厌它


的确,我们没有闭包(但是我们有一个稍微笨拙的匿名函数),lambdas&函数作为第一类对象。在某种程度上,我认为静态方法可以用来将函数模拟为第一类对象

静态方法使测试变得困难,因为它们是不可替代的,就这么简单

静态方法如何“模拟”函数作为第一类对象1?可以说,在这方面,他们比任何其他人都糟糕。通过创建单个方法接口,您可以将函数“模拟”为第一类对象,实际上,Google的Java集合在许多地方(对于谓词、投影等)都做到了这一点。静态方法无法做到这一点——没有办法(反射除外)传递“当您想要应用函数时,使用此方法”的概念

不,我看不出静态方法在这里有什么帮助。它们不鼓励状态更改(因为唯一可用的状态是全局状态和通过参数传入的任何可变状态),但它们在“函数作为第一类对象”方面没有帮助

C#对此有更好的支持(使用lambda表达式和委托),但即使是这样,也没有它可能具有的一般性(例如,将其与F#进行比较)



1从Java 8开始,方法引用将允许将方法转换为适当的单一方法接口实例,这将使所有这些变得更加相关。早在2009年,这已经是一个漫长的过程了…

我对静态方法最大的反对是,它们不是多态的,并且它们不用于面向对象的w是的,取而代之的是类(而不是对象)来访问它们。

Functional!=函数,我将声明一个方法!=函数

Java是一种静态类型的、面向对象的语言。Java也以这种方式保持了相对的纯洁性,但它离函数式语言还差得远

虽然你确实可以用命令式编程来模仿函数式编程的行为,但你永远不会得到你想要的lambda演算的简洁语法。在某种程度上,如果语言不支持正确的lambda演算,它就不是函数式编程语言

C++有函数,C++也有两种函数,成员函数和函数。当你说方法是一个成员函数时,因为这个方法是在对象实例上调用的,但是当你说静态方法时,你只需要函数(C/C++ C++中的函数)。这只是一个用于引用代码元素的词汇表。在Java代码不能存在于类之外的情况下,方法会暗示它属于某个类,即类型

到目前为止,我所说的一切都与函数式编程无关,但我认为你已经明白了你错的地方

我建议您看看纯函数式编程语言,比如Haskell或Erlang,因为函数式编程语言通常也没有闭包


你声称静态方法可以用来模拟函数作为第一类对象,这听起来真的很奇怪。它听起来更像是一种动态编程语言,而不是函数编程。

如果你只使用静态方法,那么你是在以过程的、非面向对象的方式编程


然而,我能想到的唯一可行的上下文是在引入面向对象之前的第一节编程课程中。

在Java中,不能将一个函数作为另一个函数的参数

在函数式语言中,如果有函数

def addOne(i) = i + 1
您可以将其传递给另一个函数,例如将其应用于列表的所有元素

在Java中,使用

public static int addOne(int i) { return i + 1; }

没有办法做到这一点。

函数式编程的一个特征是数据的不变性。
静态
确实意味着不需要表示状态的对象(实例),因此这不是一个坏的开始。不过,您在类级别上有状态,但您可以将其设置为最终状态。
因为(静态)方法根本不是第一类函数,您仍然需要像匿名类这样丑陋的构造来接近Java中某种类型的函数编程

FP最好用函数式语言完成,因为它对高阶函数、不变性、引用透明性等都有必要的语言支持

然而,这并不意味着您不能用命令式语言(如Java)以函数式编程。也可以给出其他示例。并不是因为您是用Java编程,所以您正在进行OOP。您可以使用全局数据和非结构化控制流进行编程(
goto
)在C++语言的结构化语言中,我可以用函数语言如方案等来进行OOP。 Steve McConnell提到了用一种语言编程与用代码完成的语言编程的区别(这也是一个非常流行的参考)

所以,简而言之,如果你说“静态方法模拟一级函数”,我不同意


但是,如果我认为这是您试图理解的重点,那么您会说“静态方法可以帮助以Java函数式编程“,我同意。

您为什么要替换测试方法?我想测试的方法不是更换!如果该方法转到另一个半球上的Web服务器上,而您并不真正想要它,因为您最好使用静态模拟数据。安东评论+1。如果您不能替换依赖项,那么您的“单元”测试将测试这些依赖项以及它们真正尝试测试的方法。我认为您混淆了功能性和过程性。通讯器