av手机免费在线观看,国产女人在线视频,国产xxxx免费,捆绑调教一二三区,97影院最新理论片,色之久久综合,国产精品日韩欧美一区二区三区

java語言

Java中的繼承與組合

時間:2025-01-28 03:19:08 java語言 我要投稿
  • 相關(guān)推薦

Java中的繼承與組合

  繼承是面向?qū)ο笞铒@著的一個特性。繼承是從已有的類中派生出新的類,新的類能吸收已有類的數(shù)據(jù)屬性和行為,并能擴展新的能力。那么Java中的繼承與組合是怎樣的呢?以下僅供參考!

  當(dāng)Java 1.5引入注解,企業(yè)開發(fā)者對簡化EJB和其他企業(yè)產(chǎn)品開發(fā)抱有很大期望?梢钥匆豢赐粫r期的一篇文章用EJB 3.0簡化企業(yè)Java開發(fā)。

  然而從那時起,Java企業(yè)使用注解出現(xiàn)一些無法預(yù)料的后果和副作用,一些甚至到今天都沒有被注意到。幸運的是,并非所有的副作用都沒有被注意到,來看一些例子,在StackOverflow標(biāo)題為“Why Java Annotations?”有很多有價值的評論,“Are Annotations Bad?”這篇文章有很棒的觀點,還有“Magics Is Evil”,“Annotations…Good, Bad or Worse?”。

  java-programmer

  并非所有的注解都相同

  盡管上面許多討論都包含有價值的觀點,但并不是所有注解都是相同的。

  這里有兩類注解,區(qū)別在于他們是否在運行期影響程序。首先,說一下無害的一類,它們并不會在運行期對代碼產(chǎn)生任何影響;另一種是有害的一類,它們會修改運行期行為。無害的注解包括@Deprecated, @Override, @SuppressWarnings, 等等。有害的注解包括@Entity, @Table, @PostConstruct, @ApplicationScoped,等等。

  在無害的注解中存在一小部分注解,它們非常實用。有一些提供在編譯期間(靜態(tài)檢查)捕獲錯誤或提供安全保障。一些實用的注解包括:@Override, @NonNull/@Nullable 來自(Checker Framework), 等等。

  為什么有害的注解不好?

  我們定義了一些有害的注解,為什么要避免使用它們呢?

  想象一個標(biāo)準(zhǔn)的Java Data類擁有@PostConstruct方法。這個注解表示所標(biāo)注的方法應(yīng)該在對象創(chuàng)建好之后被調(diào)用。這個功能并不是由JVM處理,所以Date類隱式獲取未知的框架和容器,而自身語義上并沒有做任何事情。如果這些代碼并不運行在任何容器中,而只是運行在JVM中呢?這個注解大大降低了這個類的重用性。另外對于任何使用Date的地方進行單元測試就變成了噩夢,因為你必須確保每次都正確綁定post-construction,要模擬一個兼容的容器。這就有點可笑了,一個Date類需要一個容器來運行,但這確實是有害的注解對類、方法和參數(shù)的影響。

  無可否認(rèn),業(yè)務(wù)邏輯往往復(fù)雜,需要更多依賴和關(guān)系,而不僅僅是一個簡單的Date類。然而沒有理由在一個類中顯式或隱式地添加不必要的依賴或約束,有害的注解就是:依賴和約束。

  企業(yè)陷阱

  不幸的是有害的聲明在Java Enterprise 5大規(guī)模合法化。為了更正早期企業(yè)API的易用性問題,注解用來隱藏系統(tǒng)中冗余的和難用的部分。新的JEE 5被稱贊為”輕量級”和”簡單”,表面上看起來是這樣。但是一個微小的,同時也是至關(guān)重要的誤用蔓延開來。

  @Statelesspublic class DocumentRepository { public Document getDocument(String title) {

   ...

  }

  ...

  }

  如果想要獲取一個Stateless EJB,“只需要”在類上聲明@Stateless注解。確實,編寫這個類只需要只一點動作,但是請注意這個類中有害的注解綁定了幾百頁的說明文檔,而且只能在百萬字節(jié)的應(yīng)用服務(wù)器(Application Server)上運行。這又怎么能稱的上是”輕量級”呢。所以,這個注解僅僅是真正需要編寫的Java代碼的占位符而已,代碼仍需要以某種形式存在,F(xiàn)在只不過是隱藏在注解之下。

  不幸的是,這種變通方案稱為一種模式,現(xiàn)在有害的注解廣泛分布:JPA, CDI, Common Annotations, JAXB 等等。

  有害的注解有時會出現(xiàn)在錯誤的地點

  因為注解通常作為開發(fā)環(huán)境,有時有害的注解被當(dāng)做單一職責(zé)原則(Single Responsibility Principle)或關(guān)注點分離(Separation of Concerns)的最佳實踐。

  讓我們來考慮一下下面這個CDI例子:

  @ApplicationScopedpublic class DocumentFormatter {

  ...

  }

  上面的注解描述這個類應(yīng)該是一個CDI Bean,意味著它應(yīng)該只能由CDI實例化,并確保每個應(yīng)用中只有一個實例。

  這些信息并不屬于這個類。這個服務(wù)在功能上(無論什么方式)并不會對它在當(dāng)前應(yīng)用中的作用產(chǎn)生影響。這里有兩個明顯的關(guān)注點。

  一個JPA的簡單例子:

  @Entity@Table("PERSON")public class Person {

  ...

  }

  問題在于這種類往往是”領(lǐng)域?qū)ο?domain objects)”,它們直接將領(lǐng)域模型持久化。更糟的是,數(shù)據(jù)傳送對象(DTO)用來在對象之間傳送數(shù)據(jù),使得整個構(gòu)造變得脆弱,因為對象間耦合過于緊密。不管怎樣,這是一種錯誤的方式。

  所有的這些附加的功能和(或)信息應(yīng)該從這些類中分離出來,但是它們卻悄悄混在一起,因為它們”只不過”是注解。

  有害的注解有時蔓延

  注解有時會傳染其他對象;仡櫳厦婺莻CDI Bean。每個使用它的對象,每個依賴它的對象現(xiàn)在都擁有一個CDI注解,否則依賴關(guān)系樹就不會構(gòu)建成功。

  @Entity注解也一樣。因為對象之間的關(guān)系,其他對象也通過注解持久化,很快所有的持久化對象都會有這個注解。我們無法使用原生的第三方對象(除非序列化或包裝它們),我們無法使用其他持久化機制(比如用NoSQL DB存放對象)。

  這些注解使得這些對象無法復(fù)用。它們只能在一個嚴(yán)格的、受控制的、不透明的環(huán)境中使用,不能和任何東西整合。

  有什么替代品?

  是XML嗎?當(dāng)然不是,至少對于上面的例子來說不是。

  Spring框架使用配置來管理對象,因此可以用XML當(dāng)做配置文件。然而,是否某個依賴需要在運行期改變,而不通過重新編譯?如果不需要,那么很難說配置應(yīng)該用另一門語言來表示,尤其重構(gòu)困難、測試?yán)щy、管理需要特殊工具。

  真正的替代品當(dāng)然是好的Java代碼,正確封裝并解耦的。是的,用代碼來管理對象,盡管有時被當(dāng)做樣板(boilerplate),但并不算糟糕。它帶來一些好處,比如讓代碼可讀、可調(diào)試、可重構(gòu)。只有那些長片的、復(fù)雜的、冗余的樣板是糟糕的,比如“關(guān)于EJB 2.0”。但是解決方案并不是擺脫所有的樣板或用另一種語言隱藏樣板,而是簡單干凈的架構(gòu),直接而不多余的信息,簡單并合適的方式來面向?qū)ο蟆?/p>

  這也適用于JPA、Spring和其他東西。誤用注解來表示功能會發(fā)生Stcakoverflow上這個問題“Arguments Against Annotations”,為什么不用已有的工具呢:比如Java語言本身和編譯器,來解決這類問題,面向?qū)ο蠛蛙浖罴褜嵺`。

  總結(jié)

  如果注解在代碼運行期加上了額外功能和約束,那它是有害的。這很糟糕,因為它隱藏了類或方法的切面,使之難懂、難復(fù)用、難重構(gòu)、難測試。

  不幸的是Java Enterprise不理睬Java開發(fā)者社區(qū)中發(fā)對注解的聲音。所以企業(yè)級Java和其他”官方”框架更不可能重視這類問題。

  至少我們可以持續(xù)關(guān)注有害的注解,如果可能盡量避免使用,編寫新的框架和軟件替換掉注解,不會出現(xiàn)有害注解所帶來的問題。

【Java中的繼承與組合】相關(guān)文章:

java的繼承與組合的區(qū)別07-19

Java 繼承07-04

java的繼承總結(jié)08-06

Java繼承結(jié)構(gòu)中類的初始化10-09

java語言的接口與繼承09-09

java繼承是什么06-11

Java語言的繼承結(jié)構(gòu)06-21

Java語言繼承的要點10-24

java繼承抽象類07-28