熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

進入Harmony 世界,類庫開發最佳實踐

2022-06-13   來源: JSP教程 

  

  Apache Harmony 是 月宣布的開放源碼 Java SE 實現本文是由 部分組成的 進入 Harmony 世界 系列文章的第四篇這個系列主要介紹 Apache Harmony 項目的內部實現最新發展現狀和開源 Java 開發的模式並鼓勵和歡迎大家參與到 Harmony 的社區中來

  本文較詳細地介紹了 Harmony 項目類庫(API庫)開發過程當中的經驗從架構設計和軟件工程的角度介紹了類庫開發過程當中積累的類庫模塊的劃分測試優先的開發模式結對編程代碼審核等等最佳實踐

  類庫模塊劃分

  類庫模塊的劃分是 Harmony 項目類庫總體設計上的主要特點通過將龐大的 JSE 類庫劃分為若干個相對獨立而且小規模的功能模塊Harmony 的開發者簡化了類庫實現的過程降低了開發類庫的風險類庫模塊的劃分原則和具體劃分方式是項目進行和結構設計實踐當中不斷總結和歸納出來的

  Harmony 模塊化背景和目標

  實現一個完整的兼容的開源 JSE這是一種很棒的開創性的想法但它的實現有著相當的難度有很多的問題需要注意開源軟件的開發流程具有一定的自由性和不確定性通常的情況是來自世界各地的開發者在一個組織的統一協調下分工合作不定期的提交一些功能模塊然後集成到一個大的平台產品當中這樣的開發方式是開源軟件的固有特征但是對於 JSE 這樣的龐大體系這樣的開發模式會增加產品的風險為了減小風險便於平台的升級和維護就要充分考慮以下問題合理的劃分平台定義好模塊之間的接口以及降低耦合性總結來說有以下幾個目標


    符合 JSE 基本結構

      與現有的 JSE 實現功能上兼容的同時在基本的大的組件方面也要做到一致如 JVM類庫JIT 組件等等大規模組件必須對應一致這樣可以使 Java 類庫的開發工作易於管理開源社區的參與者可以集中開發他擅長的模塊


    獨立開發

      為了開發的便利和風險的降低平台的模塊必須實現獨立開發各個模塊之間盡量減少耦合這樣才可以發揮開源項目的優勢避免其缺陷


    模塊替換

      在 Java 的開源世界裡隨時都有很多開源軟件的出現如果出現了某些優秀的開源 JSE 組件應該允許它們方便的替換進來另外如果發現本身某一個模塊實現上的不足也可以方便的替換出去而不影響整個平台


    共享組件

      除開提供完整的 JSE 實現這個項目的另外一個有價值之處就是在於為開源社區提供共享的 JSE 組件這個目標十分重大因為一個完整的 JSE 平台本身就意味著了聚集了很多有價值的組件所以平台的設計必須確保這些組件可以方便的被共享和重用

  針對以上目標在 Harmony 項目中采用了模塊化的劃分方式在 Sun 公司的最初設計裡面根本沒有考慮過對 Java 模塊化也沒有開源的想法所以原有的耦合性是比較大而且這個劃分既要有全局的劃分即把整個 JSE 劃分為幾個大的組件如 JVMAPI 類庫Tools 等等也有對組件內部的劃分例如把類庫進一步劃分成一些模塊不同的模塊實現不同的功能

  類庫設計

  完整的 JSE 平台的模塊化設計首先應該在最抽象的層次按照設計目標劃分出整體的模塊組件規定好它們的互聯規范比如對類庫虛擬機間接口的定義然後應該在比較具體的層次在比較大的組件當中再次劃分子模塊例如類庫的進一步劃分

  類庫(Class Library)是 JSE 當中最復雜和最常用的部分它為 Java 開發者提供了豐富的編程接口給 Java 應用程序提供了基礎類庫Harmony 類庫的目標是要實現一個標准 JSE 類庫和現有的 Sun 的 JDK 兼容一致雖然不會增加特性但是在完全不涉及 Sun 的源代碼的前提下僅僅依靠公開的 Java 文檔設計和開發這樣的類庫依然是一項艱巨的工作

  Harmony Class Library 分為三十多個模塊如果我們從上下層次上看它們主要上分為以下四個大類主要模塊如圖所示


圖一 類庫劃分總圖
類庫劃分總圖

  應該注意到這個劃分和 Sun 公司的 JSE 結構圖並不相同這是因為Harmony 為自己項目的特點對已有的基於包(package)的類庫結構按照功能重新分析和歸類有的模塊是從包中劃分出來如 instrument 模塊做 Java 虛擬機的類重定義和管理功能它本來是 javalang 包當中的子包但是由於功能的獨特所以就被單獨分為一塊

  下面逐一介紹這四大類和主要的模塊


    基礎模塊 (LUNI) 與 NIO

      LUNI 是 LangUtilNetIO 這些模塊的首字母總稱他們和新的 NIO 模塊一起表示類庫的基礎和核心部分處於類庫的底層當然LUNI 當中也有些獨立分出模塊的子包如 instrumentmanagement 模塊這些模塊作為虛擬機監測工具類庫就不屬於 LUNI

      之所以要把 LUNI 和 NIO 同看作為基礎模塊是因為它們互相之間有著密切的聯系在實際實現中它和 IO 和非常多的底層公用兩者有緊密的聯系如 NIO 當中的 SocketChannel 和 NET 中 Socket 基本上就可以共用同一套底層代碼

      Lang 模塊就是 javalang 包中的基本模塊JVM 中的 ClassString反射和引用等類雖然在 lang 包裡面但不屬於這個模塊(屬於VMI) javalanginstrument 和 JMX(Java Management Extension) 中的 javalangmanagement 子包也不屬於這個模塊Lang 模塊主要包括基本的語言方面和類型方面的類如基本類型的包裝類(Byte Boolean 等)基礎的接口和抽象類(如 Comparable 接口和枚舉抽象類 Enum)等等另外 中的用於實現元數據技術的注釋模塊(javalangannotation)的新模塊也屬於這個模塊

      Util 模塊就是 javautil 包當中的基本模塊(它並不包括 util 當中的任何子包因為這些子包都各自有獨立的功能被分成了其他模塊)Util 模塊包含了 Java 當中最常用的集合框架(Collection Framework)集合框架當中定義了最常用的集合數據結構的表示接口如 SetMapList 等以及這些數據結構的不同具體實現如 HashSetTreeMapLinkedList 等還有一些集合工具類如 Arrays提供了基本的集合操作算法(插入查找和排序等)這個框架當中的接口和類極為重要不僅被應用程序頻繁使用而且許多類庫的實現也依賴它們所以說這個框架的性能和功能在一定程度上決定了類庫的性能和功能

      Util 模塊還包含了一些常用類如時間和區域相關的 CalendarTimeZoneLocale 等類格式輸入輸出類 FormatterScanner隨機數生成類 Random用於全球化的 ResourceBundle 類等等

      Net 模塊包括與網絡操作相關的模塊主要在 包裡面Java 語言最開始的一大亮點就是對網絡的強大支持在 Net 模塊當中網絡當中的抽象概念如 URLProxySocket(甚至有缺省的 http/ftp 等協議的實現)等都被方便的提供出來使得開發者不用關心底層網絡實現大大提高了網絡程序開發的能力

      IO 是基於流的輸入輸出模塊由於性能上的缺憾以及對異步 IO 的要求NIO 作為一個新的 IO 模塊加入了 Java 庫IO 和 NIO 聯系緊密在 NIO 出現以後IO 當中的絕大部分都用 NIO 重新實現了NIO 基於緩沖(Buffer)實現了異步 IO對於文件網絡等基本 IO 都做了新的實現和優化

      NIO 是新的 IO 模塊的縮寫(除了字符集(Charset)以外的模塊)它是 Java 提出來的最重要的新特性之一與舊的 IONET 模塊相比它支持非阻塞模式(nonblocking)提出了 Buffer 概念來替代數組目的是提高整體的 IO 效率


    通用模塊 (Common)

      在 LUNI 的上面是許多相對獨立的模塊組成的通用功能模塊區其中有很多是從 javautil 包當中分離出來的這些模塊一般是實現了 Java 某一重要方面的專門功能這些功能適用廣泛可以為桌面應用程序和企業級服務程序提供豐富的數據結構和操作功能

      Concurrent 是 JSE 版本提供的新組件這個模塊主要提供 Util 模塊當中集合框架的線程同步功能是一個幫助開發者簡便實現線程安全的容器和集合的模塊這個模塊雖然主要為集合框架提供支持但是它的工作是多線程方面的為了獨立開發的需要被單獨分為一個模塊

      Archive 模塊實現了 zip 壓縮文件的算法提供了 jar 文件(使用 Zip 算法的壓縮文件)生成讀取和管理的功能為 Java 程序的壓縮發布和傳播提供了便利

      Log 模塊(logging)是提供程序日志信息管理的組件這個模塊實現了多種形式的日志信息表示方式(文件控制台網絡流等)提供了多種日志權限的管理為記錄程序的運行狀態和 debug 提供了便利

      Prefs 模塊是提供用戶配置信息管理的組件這個模塊比較特殊因為它必須為不用 OS 平台提供不同的 Java 實現

      Regex 模塊是提供 Java 正則表達式的組件這個模塊實現了類似 Perl 語言的正則表達式支持提供了字符串驗證查找等功能這個模塊被 Java 類庫和應用程序廣泛使用提高了軟件開發中字符串操作的效率和可靠性

      Charset 模塊是 javanio 的子包是提供 Unicode 字符集管理和轉換的組件雖然這個模塊被定義在 nio 的包當中但是它只是用到了 nio 的數據結構而已功能上比較獨立Harmony 在設計時將它單獨分開

      Text 模塊是一個文本解析組件這個模塊實現了文本格式管理和解析功能

      SQL 模塊是提供通用數據庫 SQL 語言操作和查詢的組件這個模塊提供了對於數據庫查詢和操作的一般框架和數據結構

      其他的通用模塊還包括數學 Math 庫Java Beans 等等


    企業級模塊 (Enterprise)

      企業級模塊區由一些比較高級的企業級應用模塊組成雖然它們被稱為企業級模塊並不代表只被用於企業級系統開發當中而是指它們一般被 JEE 程序應用涉及一些企業級的特性和功能某些企業級模塊在桌面應用當中也會用到甚至於還十分基礎和重要如 Security 模塊

      這個模塊區的劃分主要是因為平台實現的原因因為這些模塊有一些通用的特性與企業級應用相關如 XMLRMI 等這樣符合設計的目標利於獨立化開發

      Security 模塊既包括 javasecurity也包括 javaxsecurity及其子包它們定義了豐富的安全性概念和操作這個模塊當中的某些部分比較底層甚至出現在 JVM 的類庫當中但是主要的功能還是用於企業級應用的安全驗證例如標准的公開密鑰算法授權證書報文摘要等等所以這個模塊被分到了企業級模塊類

      JNDI 模塊存在與 javaxnaming包及其子包當中是一個典型的企業級應用模塊用於企業級命名空間管理JMX 模塊是一個 版本新引入的模塊存在於 javaxmanagement 當中實現了對 Java 平台自身的監控和管理它的出現是 Java 在自身信息管理方面的發展

      SQL 模塊提供了標准的 SQL 數據庫訪問構架JDBC 模塊存在於 javaxsql 當中和 SQL 模塊不同的是它提供了一種具體的數據庫訪問功能而非通用的框架等等


    客戶端模塊 (Client)

      客戶端模塊主要指的是桌面應用程序用到的模塊例如用戶界面 swingawt 和 applet 等等這個模塊在 Java 語言的早期比較流行但是這些桌面應用因為它們比較慢而且用戶界面比較差而不受重視尤其是新的 Java 用戶界面庫 SWT 的出現以後隨著 Java 的進一步發展AWT 和 SWING 也有了進一步的發展最近 JSE它們已經比較完善了而且Harmony 對 JSE 平台兼容性的要求也需要開發者去實現它們

      這些模塊包括 applet 模塊 awt 界面模塊 swing 界面模塊print 打印功能模塊sound 聲音處理模塊Swing 和 awt 界面模塊占據了整個 JSE 平台 Java 代碼量的相當大一部分據稱幾乎超過 %

   

  測試優先開發模式

  有了類庫模塊的劃分開發者就可以針對某一個模塊進行具體的開發了在具體的類庫開發過程當中開發者必須保證代碼的正確性以及代碼行為跟已有參考實現 RI(Reference Implementation即現有的商業 JSE 的實現如 Sun 的 JDK)的兼容性這些必須通過詳細的單元測試來保證在實踐當中Harmony 的開發者采取測試優先的開發模式來保證這一點

  測試優先或者稱測試驅動(Test Driven)的原則是為了保證軟件的質量將軟件的測試優先考慮在分析設計實現和集成等等開發步驟當中首先完成相應的測試代碼來保證軟件產品質量的原則這是 XP (極限編程)實踐當中一個很重要的內容

  在 Harmony 項目當中由於開源的 JSE 實現必須和現有的商業的 JSE 實現保持兼容所以測試優先原則受到了十分的重視我們根據項目特點在實現 API 庫的開發過程中提出了具體的測試優先實踐方案用於 API 實現的單元測試開發一個具體的 Java 類時采用以下的流程


    閱讀規范

      首先開發者將仔細閱讀這個類的 API 公開的規范文檔以充分了解這個類的基本情況和功能其中每一個公開函數和公開域的含義和功能必要的數據結構和算法特殊情況的處理方法和異常拋出的規則以及類與類的公開函數間的關系等等有了這樣的了解就可以對這個類的實現以及在整個模塊中它起的作用有一個詳細的認識


    完成單元測試代碼

      根據以上了解開發者將使用 JUnit 這個測試工具編寫相關的盡可能完備的單元測試代碼覆蓋文檔上所提到的所有可能的輸入輸出情況和對象狀態情況

      一般針對每一個類開發者都要實現一個 JUnit 測試類(test class)針對這個類當中的每一個方法要實現若干個測試方法分別對應於不同的輸入輸出對象狀態要覆蓋所有正常和異常情況針對規范中提到的其他特性例如多線程同步和序列化支持等也要給出相應正常和異常的測試而對每一個包(package)都有一個測試包(test suit)

      在 Harmony 的進一步開發過程中也有人提出使用 TestNG 等測試構架用於 Harmony 這種大規模的總的單元測試現在這個還在討論中


    測試 RI 的實現

      有了這些的測試代碼開發者可以開始測試 RI 的具體表現開發者在 RI 的實現下運行測試將不通過的測試進行分析和修改確保測試全部通過當然有些時候開發者可能發現 Sun 的實現並不符合規范要求或者和基本邏輯不符這個時候開發者記錄這個差異然後保持測試結果與 API 規范的要求相一致

      這一步的主要目的是在分析和修改這些測試的過程當中開發者可能會發現原有測試代碼當中很多不完備和沒有考慮到的情況通過測試可以進一步完善測試代碼


    編寫實現代碼

      當測試通過了以後開發者等於已經從規范定義和代碼實例兩個方面掌握了這個類的行為和特性可以開始正式編寫開源的實現代碼了當然在編寫過程中測試代碼也可以進一步的完善


    測試實現代碼

      最後開發者將開源的實現代碼通過測試在測試中開發者需要不斷的修改自己的實現使得開源的實現和 RI 的實現一樣同樣全部通過測試(當然RI 的 Bug 部分除外)這樣開發者最終得到了一份和 RI 的實現兼容的開源實現

      在此同時我們還得到了一份可靠的單元測試代碼這份測試代碼可以被反復的使用並且實現測試的自動化十分有利於項目的增量開發和持續集成中的回歸測試

  測試優先的主要流程如圖所示

  圖二 測試優先流程
測試優先流程

  Harmony 項目當中使用的流程是一個測試優先原則的很好實踐在這裡測試不是一種附加的技巧不是為了寫測試而寫測試而是實現實際代碼的必經之路在現在一般的軟件項目當中雖然測試優先是一個被反復提倡和強調的概念因為開發者如果不寫測試工程依然可以被開發出來(尤其是大量時間比較緊的項目)這時的測試就是一個可能被忽略的環節但是這樣會出現質量隱患而在 Harmony 項目的特點就是我們開發的軟件必須要和現有的實現保持兼容而且公開的文檔很難直接指導實現工作有很多的細節必須通過對現有實現的單元測試來得到答案沒有測試開發根本無從下手這時的測試就成了不可能被遺忘和忽略的一環而且因為有了現有 RI 的實現測試可以被提前開發出來並且得到了進一步的優化和測試這樣這個開源項目就真正實現了測試優先

   

  結對編程

  有了以上的開發方式Harmony 的開發者如何在團隊協作的環境下來有效的實施這些原則和方法呢?在實踐當中開發者總結和歸納出了一套以結對編程為主的團隊協作方式

  結對編程(Pair Programming)也是 XP 當中的一個重要實踐它的基本理論是兩個開發者結成開發對子一起開發一個模塊一個人編碼的時候另外一個人在旁邊進行檢查和核對隨時對編碼過程中的錯誤和疏忽做出糾正這個開發模式似乎是在浪費人力資源讓兩個開發者干一份工作但是在很多項目的開發當中這種模式可以大大降低程序修改和返工的概率提高質量總的來說反而提高了人力資源的利用因為兩個開發者都在干有意義的事情並沒有浪費人力

  在 Harmony 項目當中基於測試優先的原則開發者提出了自己的結對編程實踐方法如圖所示兩個開發者組成一個開發對子(Development Pair)一起閱讀兩個類的 API 規范文檔 然後兩人分別完成一個類的測試代碼接著兩人交叉換位依據對方完成的測試代碼完成另外一個類的實現代碼

  圖三 結對編程
結對編程

  這樣雖然兩人沒有如傳統結對編程裡面提到的那樣直接監督對方編程但是通過測試代碼兩人實現了相互獨立的檢查對方的工作使得任何一個類都有兩個人來完成增加了交流機會和發現問題的機會提高了產品的質量這個方法基於測試工作的重要地位以及測試優先的工作流程是保證開源項目品質的一個很有效的方法

  代碼審核

  對於這個項目而言代碼本身就是產品需要開放出來給全世界的人看所以代碼的可讀性和書寫規范就變得十分重要為此開發者制定了統一而嚴格的規范(Checklist)使用公認的優秀的編碼風格來實現這個平台從變量命名的規范到程序結構的安排這個規范十分清晰而完整

  為了保證這個 Checklist 被很好的落實開發人員在 Development Pair 的基礎上在某些情況下(如新成員加入對工作尚不熟悉時)添加了一個新的角色代碼審核員(QA)

  一般地在需要 QA 的 Development Pair 當中有 Level 和 Level 兩個 QA 角色Level 的 QA 主要負責檢查結構和代碼的缺陷和隱患例如可能的 Bug不妥的設計結構等等Level 的 QA 主要負責檢查除開 Bug 以外的表面上的問題例如注釋的書寫問題代碼命名規范和容易引人混淆的代碼書寫等等

  這樣的安排主要是為了加速培訓新成員(對於 QA)以及保證代碼質量(對於 Development Pair)在實踐當中有著很好的效果為了在一定時期內可以最大程度的調動成員的積極性也為了讓每個成員都有機會在不同的角色上面得到鍛煉開發人員設計了一個輪換游戲(Rotation Game)以一定周期內的表現來決定下一個周期各位開發人員的角色

  這個游戲的規則比較靈活以三個 Development Pair 為例Rotation Game 的規則如下圖所示其中藍色表示代碼開發人員黃色表示 Level 的 QA紅色表示 Level 的 QA每一個小Pair代表兩個人的對子

  圖四 輪換游戲
輪換游戲

  在實踐當中這樣的 QA 代碼審查和角色輪換的工作大大提高了代碼的質量這樣的工作方式和上述單純的結對編程方式相結合靈活應用很好的保證了 Harmony 項目的代碼質量要求

  除開人工審核以外自動審核的作用也很有效除了使用 Eclipse 內部的代碼格式化功能以外開發者還統一將 Eclipse 內部的代碼編譯要求提高將所有被忽略的代碼規范要求都設置成警告級別使得代碼中的很多小問題例如注釋的格式不對等等都成為了警告開發者原則上必須消除所有警告如圖所示另外開發者還使用和配置代碼檢查工具 Checkstyle對代碼的深層次問題例如可能出現的內存洩漏都做出了檢查

  圖五 代碼審核自動化的手段之一
代碼審核自動化的手段之一

  此外開發者還定期召開代碼審核會議利用以前積累的經驗規則用人工檢查的討論方式來改進代碼質量這也是開發者之間促進交流和溝通的一個很好方式

  除開靜態的檢查以外開發者還會使用 Purify 等動態檢查工具用實際運行的方式來發現程序的缺陷如內存洩漏問題等

   

  結束語

  本文介紹了 Harmony 項目進行當中尤其是在 API 庫開發過程當中逐漸積累和總結出來的最佳實踐經驗這些經驗不是不變的而是隨著項目的進行逐漸改進

  參考資料

  學習


閱讀 進入 Harmony 世界 系列文章的其它部分


從 Apache Harmony 項目的 官方網站 中獲得更多相關信息


了解 Harmony 的類庫 API 的覆蓋率統計報告 JDK JDK


如何 參與 到 Apache Harmony 項目


定制 bugzilla 進行項目管理(developerWorks Java 月) 介紹了如何在 Apache Harmony 項目中使用流行的缺陷跟蹤系統 — Bugzilla


追求代碼質量 專欄來自質量專家 Andrew Glover 關於測試覆蓋工具方面的專家意見


讓開發自動化 專欄專門探索軟件開發過程自動化的實際應用


揭開極端編程的神秘面紗 專欄幫助您理解 XP並解釋為什麼它這麼重要

  獲得產品和技術


Apache Harmony 的二進制版本 下載


IBM Apache Harmony 開發包(VM Environment) 下載


IBM JDK 下載

  作者簡介

  

  Author1 photo

  羅毅 就讀於南京大學計算機系研究的領域包括軟件過程和工作流您可以通過a聯系到他


  Author2 photo

  蔡一超就讀於南京大學軟件學院 對java和Linux技術有濃厚的興趣您可以通過聯系到他


  Author1 photo

  胡睿目前就職於 IBM 中國開發中心 Harmony 開發團隊 主要負責類庫開發的技術工作對 JSEJEEC/C++全球化技術軟件測試等有濃厚的興趣另外他對歷史電影音樂與羽毛球等也十分熱愛您可以通過聯系到他


From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19428.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.