?
快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

官方金沙娛網站下載:采用 Javadoc 形式的集成文檔有利有弊

?

級別:中級

Brian Goetz([email protected]

首席顧問,Quiotix Corp

2002 年 10 月

Java 說話按照 Javadoc 注釋約定采納了一種集成的措施來進行 API 文檔體例。Javadoc 對象可以贊助天生好的 API 文檔,然而大年夜多半 Java API 文檔卻很糟糕。由于它是源代碼的一部分,以是 API 的文檔體例職責終極照樣落到了工程師身上。在本文中,Brian 對 Java 文檔體例實踐確當前狀態進行了嚴峻的品評,同時供給了一些關于若何編寫更有用的 Javadoc 的準則。

對付大年夜多半 Java 類庫來說,Javadoc 是獨一的文檔。而且,除了商業軟件組件之外,許多 Java 類不會用到 Javadoc。雖然 Javadoc 作為 API 參考對象很出色,但對付懂得類庫是若何組織的和應該若何應用它來說,它卻是一種十分差勁的措施。并且即便用了 Javadoc,它平日只包孕有關措施完成了什么的最基礎信息,而輕忽了諸如差錯處置懲罰、參數及返回值的感化域和范圍、線程安然、鎖定行徑、前置前提、后置前提、不變前提或副感化之類的緊張特點。

向 Javadoc 進修

對付包括大年夜多半開放源碼包和大年夜多半內部開拓的組件在內的許多 Java 對象而言,實際環境是:包括 Javadoc 在內,險些所有類庫或組件都不具有有效的文檔。這就意味著開拓職員要從 Javadoc 進修應用對象,而且我們應該斟酌根據這一現實組織我們的 Javadoc。我常常開玩笑說:現在,Java 法度榜樣員必要具備的最緊張的技能之一是純熟地應用 Google 和 Javadoc 來對那些文檔體例得十分糟糕的 API 進行“逆向工程”。這可能是真的,但卻并不十分可笑。

大年夜多半 Java 包都有某種“根”工具,它是在獲得該對象內的任何其它工具之前,必須創建的第一個工具。在 JNDI 中,該根工具是 Context,而在 JMS 和 JDBC 中,它是 Connection。假如有人奉告您 JDBC 中的根基工具是 Connection,以及若何得到這一工具,那么接著您很可能會從 Javadoc 中經由過程仔細不雅察 Javadoc 中可用的措施列表找到若何創建并履行 Statement,以及若何迭代天生的 ResultSet。但您若何知道得到 Connection 是您的第一步呢?Javadoc 在包內按照字母順序組織類,在類中按照字母順序組織措施。遺憾的是,Javadoc 中沒有神奇的“從這里開始(Start Here)”暗號把讀者帶到瀏覽 API 的邏輯開始位置。

包描述

最靠近“從這里開始”暗號的是包描述,但它卻很少獲得有效的應用。假如將文件 package.html 與源代碼一路放在一個包中,那么標準的 doclet 會將已天生的 package-summary.html 文件中的內容連同類列表一路放在該包內。遺憾的是,天生我們都很認識的 HTML 文檔的標準 doclet 卻無法使包描述易于找到。假如您單擊左上窗格中的某個包,那么這會在左下窗格中孕育發生措施列表,但并不會在主窗格中孕育發生包的擇要 ? 必須單擊左下窗格中的包名稱來查看擇要。但沒緊要,終究大年夜多半包并沒有包描述。

包文檔是一個放置“從這里開始”文檔的極好的地方,這一文檔用來概述包做什么、主要摘如果什么以及從何處開始瀏覽包的 Javadoc。

類文檔

除包文檔之外,特定于類的文檔對付贊助用戶徹底懂得新對象也能起到緊張的感化。類文檔當然應該包括此特定類做什么的描述,但還應該描述該類與包中的其它類若何關聯,分外是要標識任何與該類相關的工廠類。例如,JDBC 中的 Statement 類文檔應該闡明:Statement 是經由過程 Connection 類的 createStatement() 措施得到的。這樣,假如一個新用戶偶爾進入 Statement 頁面,那么他會發明首先他必要得到 Connection。對每個類都利用這一約定的包會迅速為用戶指出根工具,用戶因而能夠輕車熟路。

由于 Javadoc 是環抱對特定類進行文檔體例而設計的,是以在 Javadoc 中平日沒有顯著的位置來放置演示幾個相關類一路應用的示例代碼。但因為一味地偏重于特定類或措施的文檔體例,我們掉去了評論爭論若何組合包中內容的時機。假如對付根工具,在包文檔或類文檔中有一個演示一些基礎用法的簡單代碼示例,則對付許多用戶來說,將是異常有用的。例如,Connection 類文檔可以有一個簡單示例,該示例獲取連接、創建預編譯語句、履行該語句并迭代結果集。從技巧上說,這可能不屬于 Connection 頁面,由于它還描述了包中的其它類。然而,尤其是當結合了上面那種引用當前類所依附的類的技巧時,用戶才能異常迅速地找到獲取簡單的實用示例的道路,不管類的組織要領若何。

糟糕的文檔 == 糟糕的代碼

對付大年夜多半 Java 類庫來說,除了那些作為打包組件出售的商業產品之外,要么沒有 Javadoc,要么異常糟糕。因為存在的事實是對付大年夜多半包來說,Javadoc 是我們擁有的獨一文檔,這基礎上意味著使我們自己陷入了這樣的逆境:除了作者之外,其他人沒法應用我們的大年夜部分代碼 ? 假如不付出重大年夜的“考古”一樣的努力,至少會這樣。

因為文檔現在是代碼的一部分,是以我覺得是軟件工程社區形成一個共識的時刻了,這便是,縱然代碼很出色,假如文檔很糟糕,也應該被覺得是差勁的代碼,由于不能有效地重用。單元測試不久前還聲望不佳,只是到了近來它才受到了許多工程師的青睞,就和它一樣,為了改良我們臨盆的軟件的靠得住性和可重用性,API 文檔也必須成為開拓歷程的一個集成部分。

編寫 Javadoc 便是某種形式的代碼反省

編寫合理的 Javadoc 也會孕育發生副感化,它迫使我們進行某種形式的代碼反省,來鉆研類的體系布局和它們之間的關系。假如單個包、類或措施很難體例文檔,那么或許可以考試測驗同時對多個包、類或措施進行文檔體例,這應該是個提示,即可能它必要從新設計。

文檔的自我反省方面使得某些方面加倍緊張,即在開拓歷程中盡早編寫 Javadoc,然后跟著代碼的賡續開拓,按期對其進行反省,而不是僅僅等待代碼完成再編寫文檔(假如有殘剩光陰的話)。后一種策略十分常見,它將編寫文檔拖到項目著末,而那韶光陰安排十分首要,開拓職員的壓力也很大年夜。結果官方金沙娛網站下載再常見不過了,便是圖 1 所示的那種一文不值的文檔,它只供給了“文檔假象”。用戶官方金沙娛網站下載真正必要的是懂得該類的事情道理,而該文檔卻沒有供給任何這樣的信息。

清單 1. 范例的一文不值的 Javadoc

/**

* Represents a command history

*/

public class CommandHistory {

/**

* Get the command history for a given user

*/

public static CommandHistory getCommandHistory(String user) {

. . .

}

}

那么好的文檔包括哪些內容呢?

上面描述的組織技巧(在類描述中引用相關類或工廠類,也包括了包概述和代碼樣本)是形成優秀文檔的好起頭。它有助于新用戶應用 Javadoc 懂得新對象。

但體系布局的概述只完成了義務的一半。另一半則是具體地解釋措施做什么和不做什么、在什么前提下運行以及它們若何處置懲罰差錯前提。大年夜多半 Javadoc 都沒有完全供給所需的信息,即就是那些充分描述了措施在期望環境下的行徑的 Javadoc 也是如斯,這些缺少的信息包括:

措施若何處置懲罰差錯前提或分歧要求的輸入

若何將差錯前提傳回給調用者

可能會拋出哪個特定非常的子類

哪些值對付輸入是有效的

類不變前提、措施前置前提或措施后置前提

副感化

在措施之間是否有緊張聯接

類若何處置懲罰多個線程同時造訪一個實例的環境。

Javadoc 約定供給了 @param 標記,它讓我們除了能夠對參數的名稱和類型體例文檔之外,還可以對其意義體例文檔。然而,并不是所有的措施都能很好地吸收參數的任何值。例如,雖然可以合法地向任何獲取工具參數的措施通報空值(null)而不違反類型反省規則,但并不是所有的措施都能在傳入空值時正常事情。Javadoc 應該顯式地描述有效的參數范圍,假如它盼望某個參數非 null,那么它應該這樣描述,而假如它期望參數值在某個范圍內,例如某種長度的字符串或大年夜于 0 的整數,那么它也應該那樣描述。并非所有措施都仔細反省其參數的有效性;不進行有效性反省也沒有體例關于可吸收的輸入范圍的文檔,這二者的結合為劫難埋下了隱患。

返回代碼

Javadoc 使得描述返回值的意義變得很輕易,但正如措施參數一樣,@return 標記應該包括對可能返回的值范圍的具體描述。對付工具取值的返回類型而言,它會返回空值嗎?對付整數取值的返回類型而言,結果會限定在一個已知值或非負值的聚攏上嗎?任何返回代碼都有特殊意義嗎,例如從 java.io.InputStream.read() 返回 -1 表示文件停止符?返回代碼會被用來表示例如假如無法找到表項則返回空值那樣的差錯前提嗎?

非常

標準 doclet 復制措施的 throws 子句,但 Javadoc @throws 標記應該更為詳細。例如,NoSuchFileException 是 IOException 的子類,但 java.io 中的大年夜多半措施卻只被聲明為拋出 IOException。然而,措施可能自力于其它 IOException 而拋出 NoSuchFileException,這是調用者要懂得的很有用的事實 ? 它應該被包括在 Javadoc 中。還應該指出拋出各類非常類的實際差錯前提,以便調用者知道在給定非常被拋出時該采取什么矯正步伐。應該用 @throws 標記對措施可能拋出的每個經反省的或未經反省的非常體例文檔,并對激發拋出非常的前提體例文檔。

前置前提、后置前提和不變前提

當然,您應該對措施對工具狀態的影響體例文檔。但您可能必要體例得更具體一些,描述措施的前置前提、后置前提和類不變前提。前置前提是在調用措施前對工具狀態的約束;例如,調用 Iterator.next() 的前置前提是 hasMore() 為真。后置前提是措施調用完成后對工具狀態的約束,例如在調用 add() 之后 List 不能為空。不變前提是對工具狀態的一種約束,它包管該狀態始終為真,例如 Collection.size() == Collection.toArray().length()。

諸如 jContract 之類的按左券設計(Design-by-contract)對象容許您應用特殊注釋指定前置前提、后置前提和類不變前提,這類對象然后天生額外代碼來強制這些約束。無論您是否應用對象來強制這些期望前提,對這些約束體例文檔可以讓用戶知道要安然地應用類,他們可以做些什么。

副感化

無意偶爾候,措施除了改變工具狀態之外還會有其它副感化,例如改變相關工具、JVM 或底層謀略平臺的狀態。例如,所有履行 I/O 的措施都有副感化。有些副感化是無害的,例如保留類處置懲罰的哀求的記數。別的一些副感化則會對法度榜樣機能和精確性孕育發生重大年夜影響,例如改動通報給措施的工具的狀態,或存儲對該工具的引用的副本。諸如改動相關工具的狀態或存儲對作為措施參數通報的工具的引用之類的副感化應該體例文檔。

措施聯接

措施聯接意味著類中的兩個措施互相依附,并且都對對方的行徑做了假定。發生措施聯接的一種常見情形是:措施在內部應用同一個類的 toString 措施,并假定 toString 將以特其余措施款式化工具狀態。假如該類已經子類化并且 toString 措施被重寫了,那么這種情形可能引起問題;另一個措施會忽然不能正常事情,除非它也被重寫。假如您的措施依附于其它措施的實現行徑,那么必要對那些依附性體例文檔。而且,假如類已子類化,那么可以以同等的要領重寫兩種措施以便使子類仍能正常事情。

線程安然

應該體例文檔的最緊張的行徑之一是線程安然,而對它險些從未體例文檔。這個類是線程安然的嗎?假如不是,那么是否可以經由過程用同步封裝調用來使其線程安然嗎?這些同步必須同特定管程相關聯,照樣任何不停應用的管程都可以應用呢?措施得到了對付類外部是可見的工具的鎖嗎?

線程安然實際上不是二進制屬性;線程安然有幾種可標識的等級。對線程安然體例文檔,或者以致確定線程安然的等級并非老是很輕易。但未能進行官方金沙娛網站下載這一事情將導致嚴重的問題;在并發利用法度榜樣中應用非線程安然類可能引起零星的故障,這些故障經常直到支配時才呈現(那時裸露利用法度榜樣以便裝入)。而且將額外鎖定封裝在已經是線程安然的類周圍會影響機能,以致引起逝世鎖。

Josh Bloch 在他的 Effective Java Programming Language Guide(參閱參考資料)一書中對類的線程安然等級體例文檔供給了有用的分類法??梢园凑站€程安然遞減順序將類歸到下列某一組:弗成變、線程安然官方金沙娛網站下載、有前提的線程安然、線程兼容和線程對立。

這種分類是一個極佳的框架,用于在并發造訪環境下通報關于類行徑的緊張信息。不管您是否應用這一分類法都不要緊,但您應該標識您的類意圖顯示的線程安然等級。我還建議:假如措施得到對一個工具的鎖定,而該工具對付類自身的代碼外部是可見的,那么您也應該就此體例文檔,縱然這只是一個“實現細節”,以便幫忙做出全局鎖定順序(global-lock-order)決策并防止逝世鎖。

停止語

對類的行徑體例文檔遠遠不光是對每個措施做什么給出一行描述。有效的 Javadoc 應該包括對下列內容的描述:

類若何互相關聯

措施若何影響工具的狀態

措施若何將掉足前提看護它們的調用者以及它們可能看護什么差錯

類若何處置懲罰多線程利用法度榜樣中的應用

措施的參數感化域及其返回值的范圍

別的,糟糕的文檔(或以致更糟糕,沒有文檔)會導致優秀的代碼弗成用或弗成重用。經由過程在文檔上花一些額外光陰,您將為您的用戶(可能是您自己)避免無數的挫折。

參考資料

單擊文章頂部或底部的評論爭論來參加關于本文的論壇。

Sun 教程“How to Write Doc Comments for the Javadoc Tool”描述了 Javadoc 的規則和基濫觴基本理。

Josh Bloch 的 Effective Java Programming Language Guide 包孕了有關編寫更好代碼的大年夜量有用提示和指示原則。

Peter Haggar 的文章“Acquire multiple locks in a fixed, global order to prevent deadlock”(developerWorks,2000 年 9 月)描述了一種低落逝世鎖風險的技巧,但這種技巧依附于對鎖定行徑的有效的文檔。

JContract 是一種強制類左券和類約束的商業對象。

文章“Exceptional Practices”(JavaWorld,2001 年 8 月)供給了編寫 throws 子句的指示原則。

Jeremy Roschelle 的文章“Doclet your servlet”(JavaWorld,2001 年 3 月)描述了可以如何應用定制 doclet 來為 servlet 更為具體的官方金沙娛網站下載文檔。

John Farrell 在“Make bad code good”(JavaWorld,2001 年 3 月)中談到了 Javadoc 在重構 Java 類方面的緊張性。

Scott Ambler 為體例措施文檔供給了便捷的反省表(developerWorks,2001 年 8 月)。

Javadoc doclet API 讓您編寫定制 Javadoc 插件來天生不合形式的文檔,或以致從 Javadoc 注釋自動天生代碼或模式。

在 developerWorks Java 技巧專區上查找幾百篇同 Java 技巧有關的參考資料。

關于作者

Brian Goetz 是一名軟件顧問,在以前的 15 年里,他不停是一名專業軟件開拓職員。他是 Quiotix 的首席顧問,Quiotix 是一家位于加尼福利亞州洛薩圖斯(Los Altos)市的軟件開拓與咨詢公司。在盛行的業界出版物中查閱 Brian 已出版和即將出版的文章。請經由過程 [email protected] 和 Brian 聯系。

免責聲明:以上內容源自網絡,版權歸原作者所有,如有侵犯您的原創版權請告知,我們將盡快刪除相關內容。

您可能還會對下面的文章感興趣:

快三平台开户