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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

可怕的DefaultAbstractHelperImpl

發布時間:2023/12/3 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 可怕的DefaultAbstractHelperImpl 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

不久前,我們發布了這個有趣的游戲,我們稱之為Spring API Bingo 。 當形成有意義的類名時,它是對Spring的巨大創造力的贊美和奉承。

  • FactoryAdvisorAdapterHandlerLoader
  • ContainerPreTranslatorInfoDisposable
  • BeanFactoryDe??stinationResolver
  • LocalPersistenceManagerFactoryBean

上面的兩個類實際上存在。 你能發現他們嗎? 如果沒有,請玩Spring API Bingo !

顯然,Spring API遭受...

命名事物

在計算機科學中只有兩個難題。 緩存失效,命名和錯誤一處

– Tim Bray引用Phil Karlton

在Java軟件中很難擺脫其中的幾個前綴或后綴。 考慮一下最近在Twitter上的討論,這不可避免地導致了(非常)有趣的討論 :

具有接口:PaymentService實現:PaymentServiceImpl該測試應稱為PaymentServiceImplTest而不是PaymentServiceTest

— Tom Bujok(@tombujok) 2014年10月8日

是的, Impl后綴是一個有趣的話題。 我們為什么要擁有它,為什么我們要一直這樣命名呢?

規格與主體

Java是一種古怪的語言。 在其發明之初,面向對象是一個熱門話題。 但是過程語言也具有有趣的功能。 當時,一種非常有趣的語言是Ada (以及主要來自Ada的PL / SQL)。 Ada(如PL / SQL)在包中合理地組織了過程和功能,有兩種形式:規范和主體。 從維基百科示例 :

-- Specification package Example isprocedure Print_and_Increment (j: in out Number); end Example;-- Body package body Example isprocedure Print_and_Increment (j: in out Number) isbegin-- [...]end Print_and_Increment;begin-- [...] end Example;

您始終必須這樣做,并且兩件事的名稱完全相同: Example 。 它們存儲在兩個不同的文件中,分別稱為Example.ads (ad用于表示Ada,s用于說明)和Example.adb (用于主體)。 PL / SQL遵循該命令,并使用pk作為Package來命名包文件Example.pks和Example.pkb 。

Java采取了不同的方式,主要是因為多態性和類的工作方式:

  • 類既是規范又是主體
  • 接口的名稱不能與實現類的名稱相同(大多數情況下,當然有很多實現)

特別是,類可以是純規范的混合體,具有部分主體(抽象時)和完整規范和主體(具體時)。

這如何轉換為Java命名

并非所有人都對規范和機身的清晰分離感到贊賞,這當然可以爭論。 但是,當您處于那種具有Ada風格的思維方式時,那么您可能想要為每個類(至少在公開API的任何地方)都使用一個接口。 我們對jOOQ進行了相同的操作 ,在其中我們建立了以下策略來命名事物:

* Impl

與相應接口成1:1關系的所有實現(主體)都以Impl為后綴。 如果可能的話,我們嘗試將那些實現保留為私有包,并因此密封在org.jooq.impl包中。 例如:

  • Cursor及其對應的CursorImpl
  • DAO及其對應的DAOImpl
  • Record及其對應的RecordImpl

這種嚴格的命名方案可以立即清楚地表明,哪個是接口(因此是公共API),哪個是實現。 從這個方面來說,我們希望Java更像Ada,但是我們擁有出色的多態性,并且…

抽象*

…并導致在基類中重用代碼。 眾所周知,常見的基類應該(幾乎)總是抽象的。 僅僅是因為它們最經常是其相應規范的不完整實現(實體)。 因此,我們有很多局部實現,它們也與對應的接口處于1:1關系,并為它們加上Abstract前綴。 通常,這些部分實現也是私有包的,并??密封在org.jooq.impl包中。 例如:

  • Field及其對應的AbstractField
  • Query及其對應的AbstractQuery
  • ResultQuery及其對應的AbstractResultQuery

特別地, ResultQuery是擴展 Query的接口,因此AbstractResultQuery是擴展 AbstractQuery的部分實現,后者也是部分實現。

在我們的API中完全實現部分實現是很有意義的,因為我們的API是內部DSL(特定于域的語言) ,因此無論具體Field實際Substring如何,都有成千上萬種始終相同的方法,例如Substring

默認*

我們做與接口相關的所有API。 在流行的Java SE API中,已經證明這種方法非常有效,例如:

  • 館藏
  • JDBC
  • DOM

我們還做與接口相關的所有SPI(服務提供商接口) 。 就API的發展而言,API和SPI之間存在一個本質區別:

  • API是由用戶消費 ,難以實現
  • SPI由用戶實現 ,幾乎不消耗

如果您不開發JDK(因此沒有完全瘋狂的向后兼容規則 ),則通常可以安全地向API接口添加新方法。 實際上,我們在每個次要版本中都這樣做,因為我們不希望任何人實現我們的DSL(誰想要實現Field的 286方法或DSL的 677方法。這太瘋狂了!)

但是SPI是不同的。 每當您為用戶提供SPI(例如帶有*Listener或*Provider后綴)時,您都不能簡單地向他們添加新方法-至少不是在Java 8之前,因為這會破壞實現,并且其中有很多。

好。 我們仍然這樣做,因為我們沒有那些JDK向后兼容規則。 我們有更多的放松 。 但是我們建議用戶不要直接自己實現接口,而應擴展一個Default實現,該實現為空。 例如ExecuteListener和對應的DefaultExecuteListener :

public interface ExecuteListener {void start(ExecuteContext ctx);void renderStart(ExecuteContext ctx);// [...] }public class DefaultExecuteListener implements ExecuteListener {@Overridepublic void start(ExecuteContext ctx) {}@Overridepublic void renderStart(ExecuteContext ctx) {}// [...] }

因此, Default*是一個前綴,通常用于提供API使用者可以使用和實例化或SPI實現者可以擴展的單個公共實現,而不會冒向后兼容的風險。 對于Java 6/7缺少接口默認方法,這幾乎是一種解決方法,這就是為什么前綴命名更加合適的原因。

此規則的Java 8版本

實際上,這種做法表明,指定Java-8兼容SPI的“好”規則是使用接口,并使所有方法默認為空。 如果jOOQ不支持Java 6,我們可能會這樣指定ExecuteListener :

public interface ExecuteListener {default void start(ExecuteContext ctx) {}default void renderStart(ExecuteContext ctx) {}// [...] }

*實用程序或*助手

好的,這里是供模擬/測試/覆蓋專家和愛好者使用的工具。

為各種靜態實用程序方法進行“轉儲”是完全可以的 。 我的意思是, 您當然可以成為面向對象的警察的成員 。 但…

請。 不要成為“那個家伙”!

因此,有多種識別實用程序類的技術。 理想情況下,您應遵循命名約定,然后再遵守。 例如* Utils 。

從我們的角度來看,理想情況下,您甚至只轉儲所有未嚴格綁定到單個類中特定領域的實用程序方法,因為坦率地說,您最后一次欣賞何時必須經歷數百萬個類才能找到該實用程序方法? 決不。 我們有org.jooq.impl.Utils 。 為什么? 因為它將允許您執行以下操作:

import static org.jooq.impl.Utils.*;

這樣,幾乎感覺就像您在整個應用程序中都具有“頂級功能”之類的東西。 “全局”功能。 我們認為這是一件好事。 而且我們完全不贊成“我們不能嘲笑這一論點”, 因此甚至不要嘗試開始討論。

討論區

…或者實際上,讓我們開始討論。 您的技術是什么,為什么? 以下是湯姆·布約克(Tom Bujok)原始Tweet的一些反應,可幫助您入門:

@tombujok號PaymentServiceImplTestImpl!

— Konrad Malawski(@ktosopl) 2014年10月8日

@tombujok擺脫了界面

— Simon Martinelli(@simas_ch) 2014年10月8日

@tombujok Impl一切!

— Bartosz Majsak(@majson) 2014年10月8日

@tombujok @lukaseder @ktosopl根本原因是該類*不應*稱為* Impl,但我知道您無論如何一直在拖釣我們

—彼得·科夫勒(@codecopkofler) 2014年10月9日

我們走吧 !

翻譯自: https://www.javacodegeeks.com/2014/10/the-dreaded-defaultabstracthelperimpl.html

總結

以上是生活随笔為你收集整理的可怕的DefaultAbstractHelperImpl的全部內容,希望文章能夠幫你解決所遇到的問題。

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