为什么我们需要 JOOQ 的 JOOL?

Why do we need JOOL from JOOQ?

浏览 JOOQ 中的 JOOL 库,它在 Streams 上提供了大量功能接口和实用程序 classes。

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

查看 Whosebug 本身的参考链接:

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

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

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

函数中没有固定数量的参数,我认为这是最佳实践,我认为您应该使用所需的参数,不要走极端,否则会导致效率低下或代码难以阅读。如果您发现自己的函数有 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个参数的函数提供:

类型安全

因为 "odd" 参数在编译时被检查为 String 而 "even" 参数被检查为 Integer)。您不能使用可变参数函数执行此操作,因为您需要将可变参数声明为 Object...,从而失去编译时类型检查。

效率

您可以通过使用像这样的中间对象来获得编译时类型安全:

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

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

清洁度

比较前两段代码,包含 entry() 意味着需要输入和阅读更多的字母。这可能有点主观,但至少我更喜欢代码在不包含 entries.

的情况下的样子

为什么选择 jOOλ?

jOOλ 开始发挥作用以解决这些 Java API 缺陷:

  • 你有 Function 和 BiFunction 但你不能做类似的事情 TriFunction<Integer, String, Boolean, Double>。 除非你使用 jOOλ,否则你必须牺牲你的参数之一(或类型安全性)。

  • Java 完全没有元组,你需要使用 javatuples 或 jOOλ,除非你想再次牺牲类型安全。

  • Java 的 API 中还有其他不足,与这个问题无关,但 jOOλ 解决了这些问题,比如(我最喜欢的那个)传递抛出已检查异常的 lambda 的能力。

jOOλ 作者在此

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

业务逻辑中的一个普通方法...

...确实不应采用超过三个参数,因为一旦超过该数量,您的某些参数很可能以某种方式紧密相关,值得将它们重新设计成class.

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

更多技术库中的特定方法/函数...

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

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

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

因此,这些差异主要是风格上的差异。总的来说,一种方法相对于另一种方法并没有严格的优势

现在,如果你是一个碰巧使用 Java 的函数式/声明式程序员,Java 语言和 JDK API 的局限性限制您对程序的推理方式。这是 jOOλ 存在的原因之一,以帮助这些人假装 Java 语言实际上具有元组和应用于元组的函数,并且为了模拟这一点,jOOλ 必须 "overload" 相同一种函数 16 次 - 16 是任意上限(.NET 将元组限制为 8 次,Scala 将它们限制为 22 次)。

回答您的具体问题

My question is there are 1-16 parameter functional interfaces supported by this library. Do this makes sense at all?

是的,即使你平时只用度数较低的,偶尔也会发现Tuple16<T1, T2, ..., T16>有用,就像你设计classes一样,大多只有几个属性,您会发现自己偶尔会写一个具有 16 个以上属性的 class。

Though acceptable number varies according to different thought leaders on it. But no one says 16.

将您的思想从面向对象的教条中解放出来。思想领袖说某事总是有原因的。它在某种情况下是正确的,但绝不是普遍正确的。你写过 16 列的 SQL 查询吗?当然有。为什么它在 SQL 中可以接受但在 Java 中不能接受?

Also, it provides a utility class Seq which looks like is limited to sequential processing only.

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

中严重缺失

Can someone with good past experience using JOOL answer why I should be using JOOL as looks like lots of things it contains are of no use?

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