为什么我们需要来自JOOQ的JOOL?

问题描述 投票:1回答:2

JOOL浏览JOOQ库,它在Streams上提供了许多功能接口和实用程序类。

我的问题是这个库支持1-16个参数功能接口。这有道理吗?因为我一直在练习中将方法中的参数数量减少到3.虽然可接受的数量根据不同的思想领袖而变化。但没有人说16。

请参阅StackOverflow本身的参考链接:

what is the standard number of parameters that a java method should have?

此外,它提供了一个实用类Seq,看起来只限于顺序处理。

使用JOOL具有良好过去经验的人可以回答为什么我应该使用JOOL看起来像它包含的很多东西是没用的吗?

java java-8 functional-interface jool-library
2个回答
5
投票

函数中没有一定数量的参数我认为是最佳实践,我认为你应该使用你需要的东西而不会走极端,造成效率低下或使你的代码难以阅读。如果你发现自己有一个带有10个参数的函数,那么请三思而后行(或许它有意义)。

有几个库使用接收10多个参数的函数:

其原因主要是编译时类型检查。此外,您可以争论提高效率和感知清洁度。

以Guava的of函数为例:

ImmutableMap<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4)

这是这样使用的:

Map<String, Integer> m = ImmutableMap.of("Ashlyn", 127, 
                                         "Abigaile", 128,
                                         "Alexis", 132,
                                         "Ashlynn", 132);

该函数接收8个参数,提供:

Type safety

因为在编译时检查“奇数”参数为String,而“偶数”参数为Integer)。您无法使用vararg函数执行此操作,因为您需要将varargs参数声明为Object...,从而丢失编译时类型检查。

Efficiency

您可以通过使用如下的中间对象来获得编译时类型安全性:

Map.ofEntries(entry("Ashlyn", 27), 
              entry("Abigaile", 28),
              entry("Alexis", 32),
              entry("Ashlynn", 32))

顺便说一句exists in Java 9,但是你会创建4个中间对象,这些对象不是8参数版本所必需的。您还将创建一个额外的数组对象来保存varargs对象。

Cleanliness

比较前两个代码片段,包含entry()意味着更多的字母来键入和读取。这可能是一种主观的,但至少我更喜欢代码看起来没有包含entries

Why jOOλ?

jOOλ起到了解决这些Java API缺陷的作用:

  • 你有功能和BiFunction,但你不能做像TriFunction<Integer, String, Boolean, Double>这样的事情。除非你使用jOOλ,否则你必须牺牲一个参数(或类型安全)。
  • Java完全没有元组,你需要使用javatuples或jOOλ,除非你想再次牺牲类型安全性。
  • Java的API中存在与此问题无关的其他缺陷,但是jOOλ(我最喜欢的那个)能够传递一个抛出已检查异常的lambda。

4
投票

jOOλ作者在这里。

您似乎遇到的困难是,业务逻辑和特定库函数中的普通方法有些相关。他们不是。让我解释:

An ordinary method in business logic ...

......实际上不应该超过三个论点,因为一旦你超过这个数字,你的一些论证很可能是以一种值得将它们重新设计成一个类的方式强烈联系的。

这是面向对象的基础知识,适用于各种用例。

A specific method / function in a more technical library ...

另一方面,......不限于这种物体定向设计原则。在jOOλ的情况下,库实际上围绕(几个)语言限制工作,特别是缺少一流的元组支持。

许多语言(SQL是最突出的语言之一)支持元组,它们就像Java中的类一样,区别在于:

  • 作为structurally typed而不是nominally typed
  • 将它们的属性排序(可通过名称和索引访问),而不是按随机顺序排列(仅通过名称访问)

Tuple16<T1, T2, ..., T16>视为与具有16个命名属性(以及getter / setter,如果您喜欢)的Java类相同的东西。可以将Function16<T1, T2, ..., T16, R>视为接受具有16个命名属性的类的Java方法。

因此,这些差异主要是风格性的。一般来说,一种方法与另一种方法并没有真正的严格优势。

现在,如果您是一名正在使用Java的函数式/声明式程序员,那么Java语言和JDK API的局限性限制了您对程序进行推理的方式。这就是为什么jOOλ存在的原因之一,是为了帮助这些人假装Java语言实际上有元组和函数应用于元组,并且为了模仿它,嗯,jOOλ必须“重载”相同类型的函数16次 - 16是任意上限(.NET将元组限制为8级,Scala将它们限制为22)。

Answering your specific questions

我的问题是这个库支持1-16个参数功能接口。这有道理吗?

是的,即使你通常只使用程度较低的那些,你偶尔会发现Tuple16<T1, T2, ..., T16>很有用,就像你设计的课程一样,这些课程大多只有一些属性,你会发现你自己写的是一个有16个属性的偶尔课程。

虽然可接受的数量根据不同的思想领袖而有所不同。但没有人说16。

从面向对象的教条中释放你的思想。思想领袖说出一些东西总是有原因的。在一个背景下确实如此,但从来没有普遍真实。你有没有用16列编写SQL查询?当然有。为什么它在SQL中可以接受而在Java中不可接受?

此外,它提供了一个实用程序类Seq,它看起来仅限于顺序处理。

是的,这是主要的设计目标。顺序处理允许在并行处理中没有意义的相当多的附加功能,但JDK的Stream API却很少遗漏。

使用JOOL具有良好过去经验的人可以回答为什么我应该使用JOOL看起来像它包含的很多东西是没用的吗?

如果您没有看到它的用途,请不要使用它。但是从你的评论(你似乎更喜欢传递Object[]而不是类型元组),我认为你确实理解它的用法,你只是不想写下类型,因为什么是Object[],如果不是一个穷人的,无类型的元组随机学位?

© www.soinside.com 2019 - 2024. All rights reserved.