日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java 8 Friday:大多数内部DSL已过时

發布時間:2023/12/3 java 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 8 Friday:大多数内部DSL已过时 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在Data Geekery ,我們喜歡Java。 而且,由于我們真的很喜歡jOOQ的流暢的API和查詢DSL ,我們對Java 8將為我們的生態系統帶來什么感到非常興奮。

Java 8星期五

每個星期五,我們都會向您展示一些不錯的教程風格的Java 8新功能,這些功能利用了lambda表達式,擴展方法和其他好東西。 您可以在GitHub上找到源代碼 。

大多數內部DSL已過時

這是目前市場上最先進的內部DSL之一的供應商的說法。 讓我解釋:

語言很難

學習新語言(或API)非常困難。 您必須了解所有的關鍵字,構造,語句和表達式類型等。這對于外部DSL,內部DSL和“常規” API都是正確的,它們本質上是內部DSL,但流暢度較低。

使用JUnit時,人們已經習慣使用hamcrest匹配器 。 它們有六種語言(Java,Python,Ruby,Objective-C,PHP,Erlang)可用,這一事實使它們成為一個不錯的選擇。 作為特定領域的語言,他們已經建立了易于閱讀的習慣用法,例如

assertThat(theBiscuit, equalTo(myBiscuit)); assertThat(theBiscuit, is(equalTo(myBiscuit))); assertThat(theBiscuit, is(myBiscuit));

閱讀此代碼時,您將立即“理解”所聲明的內容,因為API的讀法像prosa。 但是學習用此API編寫代碼更加困難。 您將必須了解:

  • 所有這些方法來自哪里
  • 存在哪些方法
  • 誰可能使用自定義匹配器擴展了障礙
  • 擴展DSL時的最佳做法是什么

例如,在上面的示例中,三個之間到底有什么區別? 我什么時候應該使用另一個? 是is()檢查對象身份嗎? equalTo()是否檢查對象是否相等?

hamcrest教程繼續著以下示例:

public void testSquareRootOfMinusOneIsNotANumber() {assertThat(Math.sqrt(-1), is(notANumber())); }

您可以看到notANumber()顯然是一個自定義匹配器,在實用程序中的某個地方實現了:

public class IsNotANumber extends TypeSafeMatcher<Double> {@Overridepublic boolean matchesSafely(Double number) {return number.isNaN();}public void describeTo(Description description) {description.appendText("not a number");}@Factorypublic static <T> Matcher<Double> notANumber() {return new IsNotANumber();} }

盡管這種DSL的創建非常容易,并且可能也很有趣,但是出于簡單的原因,開始著手編寫和增強自定義DSL是很危險的。 它們絕不比其通用的,功能相同的同類更好-但它們卻更難維護。 考慮一下Java 8中的上述示例:

用功能代替DSL

假設我們有一個非常簡單的測試API:

static <T> void assertThat(T actual, Predicate<T> expected ) {assertThat(actual, expected, "Test failed"); }static <T> void assertThat(T actual, Predicate<T> expected, String message ) {assertThat(() -> actual, expected, message); }static <T> void assertThat(Supplier<T> actual, Predicate<T> expected ) {assertThat(actual, expected, "Test failed"); }static <T> void assertThat(Supplier<T> actual, Predicate<T> expected, String message ) {if (!expected.test(actual.get()))throw new AssertionError(message); }

現在,將hamcrest匹配器表達式與其功能等效項進行比較:

// BEFORE // --------------------------------------------- assertThat(theBiscuit, equalTo(myBiscuit)); assertThat(theBiscuit, is(equalTo(myBiscuit))); assertThat(theBiscuit, is(myBiscuit));assertThat(Math.sqrt(-1), is(notANumber()));// AFTER // --------------------------------------------- assertThat(theBiscuit, b -> b == myBiscuit); assertThat(Math.sqrt(-1), n -> Double.isNaN(n));

有了lambda表達式和經過精心設計的assertThat() API,我可以肯定,您將不再尋找用匹配器表達斷言的正確方法。

請注意,不幸的是,我們不能使用Double::isNaN方法引用,因為它與Predicate<Double>不兼容。 為此,我們必須在斷言API中執行一些原始類型的魔術,例如

static void assertThat(double actual, DoublePredicate expected ) { ... }

然后可以這樣使用:

assertThat(Math.sqrt(-1), Double::isNaN);

好但是…

……您可能會聽到自己在說,“但是我們可以將匹配器與lambda和流結合起來”。 是的,我們當然可以。 我現在已經在jOOQ集成測試中做到了。 我想跳過所有不在系統屬性中提供的方言列表中的SQL方言的集成測試:

String dialectString = System.getProperty("org.jooq.test-dialects");// The string must not be "empty" assumeThat(dialectString, not(isOneOf("", null)));// And we check if the current dialect() is // contained in a comma or semi-colon separated // list of allowed dialects, trimmed and lowercased assumeThat(dialect().name().toLowerCase(),// Another matcher hereisOneOf(stream(dialectString.split("[,;]")).map(String::trim).map(String::toLowerCase).toArray(String[]::new)) );

……那也很整潔,對嗎?

但是為什么我不干脆寫:

// Using Apache Commons, here assumeThat(dialectString, StringUtils::isNotEmpty); assumeThat(dialect().name().toLowerCase(),d -> stream(dialectString.split("[,;]")).map(String::trim).map(String::toLowerCase()).anyMatch(d::equals) );

無需Hamcrest,只需普通的舊lambda和溪流!

現在,當然,可讀性只是一個問題。 但是上面的示例清楚地表明,不再需要 Hamcrest匹配器和Hamcrest DSL。 鑒于在接下來的2-3年內,所有Java開發人員中的大多數將非常習慣于每天使用Streams API,而不是非常習慣于使用Hamcrest API,因此,我敦促JUnit維護人員不要使用使用Hamcrest以支持Java 8 API。

哈姆克雷斯特現在被認為是壞人嗎?

好吧,它過去已經達到了目的,人們對此已經有所適應。 但是,正如我們在上一篇有關Java 8和JUnit Exception匹配的文章中已經指出的那樣,是的,我們確實相信Java的人們在過去的十年中一直在樹錯誤的樹。

缺少lambda表達式已導致各種完全膨脹的庫 ,現在也有些無用的庫 。 許多內部DSL或注釋魔術師也受到影響。 不是因為他們不再解決以前遇到的問題,而是因為它們還沒有支持Java-8。 Hamcrest的Matcher類型不是功能接口,盡管將其轉換為一個接口很容易。 實際上,Hamcrest的CustomMatcher邏輯應該被拉到Matcher接口中,成為默認方法。

使用諸如AssertJ之類的替代方案,事情不會變得更好。該替代方案創建了一個替代DSL,現在它已通過lambda和Streams API變得過時了(就呼叫站點代碼冗長而言)。

如果您堅持使用DSL進行測試,那么無論如何Spock可能都是一個更好的選擇。

其他例子

Hamcrest只是這種DSL的一個示例。 本文展示了如何通過使用標準的JDK 8構造和幾個實用程序方法幾乎完全將其從堆棧中刪除,無論如何,您可能很快就會在JUnit中使用它們。

Java 8將為上個十年的DSL辯論帶來很多新的吸引力,因為Streams API還將大大改善我們看待轉換或構建數據的方式。 但是,當前許多DSL尚未為Java 8做好準備,并且尚未以功能性方式進行設計。 對于難以學習的事物和概念,它們有太多的關鍵字,可以使用函數更好地建模。

該規則的一個例外是jOOQ或jRTF之類的DSL,它們以1:1的方式對實際存在的外部DSL進行建模,繼承了所有現有的關鍵字和語法元素,從而使它們從一開始就很容易學習。

你拿什么

您對上述假設有何看法? 您最喜歡的內部DSL是什么,由于Java 8已過時,它可能在未來五年內消失或完全轉換?

翻譯自: https://www.javacodegeeks.com/2014/06/java-8-friday-most-internal-dsls-are-outdated.html

總結

以上是生活随笔為你收集整理的Java 8 Friday:大多数内部DSL已过时的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。