当前位置导航:炫浪网>>网络学院>>编程开发>>JAVA教程>>Java进阶

进入Harmony 世界,类库开发最佳实践

2006 年 12 月 14 日

Apache Harmony 是 2005 年 5 月宣布的开放源码 Java SE 实现,本文是由 5 部分组成的 进入 Harmony 世界 系列文章的第四篇,这个系列主要介绍 Apache Harmony 项目的内部实现,最新发展现状和开源 Java 开发的模式,并鼓励和欢迎大家参与到 Harmony 的社区中来。

本文较详细地介绍了 Harmony 项目类库(API库)开发过程当中的经验,从架构设计和软件工程的角度,介绍了类库开发过程当中积累的类库模块的划分、测试优先的开发模式、结对编程、代码审核等等最佳实践。

类库模块划分

类库模块的划分,是 Harmony 项目类库总体设计上的主要特点。通过将庞大的 J2SE 类库划分为若干个相对独立而且小规模的功能模块,Harmony 的开发者简化了类库实现的过程,降低了开发类库的风险。类库模块的划分原则和具体划分方式,是项目进行和结构设计实践当中不断总结和归纳出来的。

Harmony 模块化背景和目标

实现一个完整的兼容的开源 J2SE,这是一种很棒的开创性的想法,但它的实现有着相当的难度,有很多的问题需要注意。开源软件的开发流程,具有一定的自由性和不确定性。通常的情况是,来自世界各地的开发者,在一个组织的统一协调下,分工合作,不定期的提交一些功能模块,然后集成到一个大的平台产品当中。这样的开发方式是开源软件的固有特征,但是对于 J2SE 这样的庞大体系,这样的开发模式会增加产品的风险。为了减小风险,便于平台的升级和维护,就要充分考虑以下问题:合理的划分平台,定义好模块之间的接口,以及降低耦合性。总结来说有以下几个目标:

  1. 符合 J2SE 基本结构

    与现有的 J2SE 实现功能上兼容的同时,在基本的大的组件方面也要做到一致。如 JVM、类库、JIT 组件等等大规模组件必须对应一致。这样可以使 Java 类库的开发工作易于管理,开源社区的参与者可以集中开发他擅长的模块。

  2. 独立开发

    为了开发的便利和风险的降低,平台的模块必须实现独立开发,各个模块之间尽量减少耦合,这样才可以发挥开源项目的优势,避免其缺陷。

  3. 模块替换

    在 Java 的开源世界里,随时都有很多开源软件的出现,如果出现了某些优秀的开源 J2SE 组件,应该允许它们方便的替换进来;另外,如果发现本身某一个模块实现上的不足,也可以方便的替换出去,而不影响整个平台。

  4. 共享组件

    除开提供完整的 J2SE 实现,这个项目的另外一个有价值之处就是在于为开源社区提供共享的 J2SE 组件。这个目标十分重大,因为一个完整的 J2SE 平台,本身就意味着了聚集了很多有价值的组件。所以,平台的设计必须确保这些组件可以方便的被共享和重用。

针对以上目标,在 Harmony 项目中采用了模块化的划分方式。在 Sun 公司的最初设计里面,根本没有考虑过对 Java 模块化,也没有开源的想法,所以原有的耦合性是比较大。而且,这个划分既要有全局的划分,即把整个 J2SE 划分为几个大的组件,如 JVM,API 类库,Tools 等等,也有对组件内部的划分,例如把类库进一步划分成一些模块,不同的模块实现不同的功能。

类库设计

完整的 J2SE 平台的模块化设计,首先应该在最抽象的层次,按照设计目标,划分出整体的模块组件,规定好它们的互联规范,比如对类库、虚拟机间接口的定义;然后,应该在比较具体的层次,在比较大的组件当中再次划分子模块,例如类库的进一步划分。

类库(Class Library)是 J2SE 当中最复杂和最常用的部分。它为 Java 开发者提供了丰富的编程接口,给 Java 应用程序提供了基础类库。Harmony 类库的目标,是要实现一个标准 J2SE 类库,和现有的 Sun 的 JDK 兼容一致。虽然不会增加特性,但是在完全不涉及 Sun 的源代码的前提下,仅仅依靠公开的 Java 文档,设计和开发这样的类库,依然是一项艰巨的工作。

Harmony Class Library 分为三十多个模块。如果我们从上下层次上看,它们主要上分为以下四个大类,主要模块如图所示。


图一 类库划分总图
类库划分总图

应该注意到,这个划分和 Sun 公司的 J2SE 结构图并不相同,这是因为,Harmony 为自己项目的特点,对已有的基于包(package)的类库结构按照功能重新分析和归类,有的模块是从包中划分出来,如 instrument 模块做 Java 虚拟机的类重定义和管理功能,它本来是 java.lang 包当中的子包,但是由于功能的独特,所以就被单独分为一块。

 

下面逐一介绍这四大类和主要的模块。

  1. 基础模块 (LUNI) 与 NIO

    LUNI 是 Lang、Util、Net、IO 这些模块的首字母总称,他们和新的 NIO 模块一起表示类库的基础和核心部分,处于类库的底层。当然,LUNI 当中也有些独立分出模块的子包,如 instrument,management 模块,这些模块作为虚拟机监测工具类库,就不属于 LUNI。

    之所以要把 LUNI 和 NIO 同看作为基础模块,是因为它们互相之间有着密切的联系。在实际实现中,它和 IO 和非常多的底层公用,两者有紧密的联系。如 NIO 当中的 SocketChannel 和 NET 中 Socket 基本上就可以共用同一套底层代码。

    Lang 模块就是 java.lang 包中的基本模块。JVM 中的 Class、String、反射和引用等类虽然在 lang 包里面,但不属于这个模块(属于VMI); java.lang.instrument 和 JMX(Java Management Extension) 中的 java.lang.management 子包也不属于这个模块。Lang 模块主要包括基本的语言方面和类型方面的类,如基本类型的包装类(Byte, Boolean 等),基础的接口和抽象类(如 Comparable 接口和枚举抽象类 Enum)等等。另外,5.0 中的用于实现“元数据”技术的注释模块(java.lang.annotation)的新模块也属于这个模块。

    Util 模块就是 java.util 包当中的基本模块(它并不包括 util 当中的任何子包,因为这些子包都各自有独立的功能,被分成了其他模块)。Util 模块包含了 Java 当中最常用的集合框架(Collection Framework)。集合框架当中定义了最常用的集合数据结构的表示接口,如 Set、Map、List 等;以及这些数据结构的不同具体实现,如 HashSet、TreeMap、LinkedList 等;还有一些集合工具类,如 Arrays,提供了基本的集合操作算法(插入、查找和排序等)。这个框架当中的接口和类极为重要,不仅被应用程序频繁使用,而且许多类库的实现也依赖它们。所以说,这个框架的性能和功能在一定程度上决定了类库的性能和功能。

    Util 模块还包含了一些常用类。如时间和区域相关的 Calendar、TimeZone、Locale 等类;格式输入输出类 Formatter、Scanner;随机数生成类 Random;用于全球化的 ResourceBundle 类等等。

    Net 模块包括与网络操作相关的模块,主要在 java.net 包里面。Java 语言最开始的一大亮点就是对网络的强大支持。在 Net 模块当中,网络当中的抽象概念,如 URL、Proxy、Socket(甚至有缺省的 http/ftp 等协议的实现)等都被方便的提供出来,使得开发者不用关心底层网络实现,大大提高了网络程序开发的能力。

    IO 是基于流的输入输出模块,由于性能上的缺憾以及对异步 IO 的要求,NIO 作为一个新的 IO 模块加入了 Java 库。IO 和 NIO 联系紧密,在 NIO 出现以后,IO 当中的绝大部分都用 NIO 重新实现了。NIO 基于缓冲(Buffer),实现了异步 IO,对于文件、网络等基本 IO 都做了新的实现和优化。

    NIO 是新的 IO 模块的缩写(除了字符集(Charset)以外的模块),它是 Java1.4 提出来的最重要的新特性之一。与旧的 IO、NET 模块相比,它支持非阻塞模式(non-blocking),提出了 Buffer 概念来替代数组,目的是提高整体的 IO 效率。

  2. 通用模块 (Common)

    在 LUNI 的上面,是许多相对独立的模块组成的通用功能模块区,其中有很多是从 java.util 包当中分离出来的,这些模块一般是实现了 Java 某一重要方面的专门功能,这些功能适用广泛,可以为桌面应用程序和企业级服务程序提供丰富的数据结构和操作功能。

    Concurrent 是 J2SE 5.0 版本提供的新组件。这个模块主要提供 Util 模块当中集合框架的线程同步功能,是一个帮助开发者简便实现线程安全的容器和集合的模块。这个模块虽然主要为集合框架提供支持,但是它的工作是多线程方面的,为了独立开发的需要,被单独分为一个模块。

    Archive 模块实现了 zip 压缩文件的算法,提供了 jar 文件(使用 Zip 算法的压缩文件)生成、读取和管理的功能,为 Java 程序的压缩、发布和传播提供了便利。

    Log 模块(logging)是提供程序日志信息管理的组件。这个模块实现了多种形式的日志信息表示方式(文件、控制台、网络流等),提供了多种日志权限的管理,为记录程序的运行状态和 debug 提供了便利。

    Prefs 模块是提供用户配置信息管理的组件。这个模块比较特殊,因为它必须为不用 OS 平台提供不同的 Java 实现。

    Regex 模块是提供 Java 正则表达式的组件。这个模块实现了类似 Perl 语言的正则表达式支持,提供了字符串验证、查找等功能。这个模块被 Java 类库和应用程序广泛使用,提高了软件开发中字符串操作的效率和可靠性。

    Charset 模块是 java.nio 的子包,是提供 Unicode 字符集管理和转换的组件。虽然这个模块被定义在 nio 的包当中,但是它只是用到了 nio 的数据结构而已,功能上比较独立,Harmony 在设计时将它单独分开。

    Text 模块是一个文本解析组件。这个模块实现了文本格式管理和解析功能。

    SQL 模块是提供通用数据库 SQL 语言操作和查询的组件。这个模块提供了对于数据库查询和操作的一般框架和数据结构。

    其他的通用模块还包括数学 Math 库、Java Beans 等等。

  3. 企业级模块 (Enterprise)

    企业级模块区由一些比较高级的企业级应用模块组成。虽然它们被称为企业级模块,并不代表只被用于企业级系统开发当中,而是指它们一般被 J2EE 程序应用,涉及一些企业级的特性和功能,某些企业级模块在桌面应用当中也会用到,甚至于还十分基础和重要,如 Security 模块。

    这个模块区的划分主要是因为平台实现的原因,因为这些模块有一些通用的特性与企业级应用相关,如 XML、RMI 等,这样符合设计的目标,利于独立化开发。

    Security 模块既包括 java.security,也包括 javax.security,及其子包,它们定义了丰富的安全性概念和操作。这个模块当中的某些部分比较底层,甚至出现在 JVM 的类库当中,但是主要的功能还是用于企业级应用的安全验证,例如标准的公开密钥算法、授权证书、报文摘要等等,所以这个模块被分到了企业级模块类。

    JNDI 模块存在与 javax.naming包及其子包当中,是一个典型的企业级应用模块,用于企业级命名空间管理;JMX 模块是一个 5.0 版本新引入的模块,存在于 javax.management 当中,实现了对 Java 平台自身的监控和管理,它的出现是 Java 在自身信息管理方面的发展。

    SQL 模块提供了标准的 SQL 数据库访问构架;JDBC 模块存在于 javax.sql 当中,和 SQL 模块不同的是,它提供了一种具体的数据库访问功能,而非通用的框架,等等。

  4. 客户端模块 (Client)

    客户端模块主要指的是桌面应用程序用到的模块,例如用户界面 swing、awt 和 applet 等等。这个模块在 Java 语言的早期比较流行,但是,这些桌面应用因为它们比较慢,而且用户界面比较差而不受重视,尤其是新的 Java 用户界面库 SWT 的出现以后。随着 Java 的进一步发展,AWT 和 SWING 也有了进一步的发展,最近 J2SE5 中,它们已经比较完善了。而且,Harmony 对 J2SE 平台兼容性的要求,也需要开发者去实现它们。

    这些模块包括: applet 模块, awt 界面模块, swing 界面模块,print 打印功能模块;sound 声音处理模块。Swing 和 awt 界面模块占据了整个 J2SE 平台 Java 代码量的相当大一部分,据称几乎超过 50%。

 

相关内容
赞助商链接