模块化Java简介 - 编程入门网
测试。一个小模块(具有定义良好的API)通常比应用整体更 好测试。在GUI应用中尤其如此,GUI自身可能不好测试,但是其调用的代码却是可测试的 。
模块化的另一个好处是便于进化。尽管系统整体有一个版本号,但实际上,其下有多 个模块及相应版本(不论开源与否,总有一些类库——甚至是Java版本—— 是系统所依 赖的)。这样,每个模块都可以自己的方式自由地进化。某些模块进化得快些,另一些则 会长期保持稳定(例如,Eclipse 3.5 的org.eclipse.core.boot从2008年2月以来一直没 有改变过)。 模块化也可给项目管理带来方便。如果一个模块公布的API可供其他模块预先使用,那 么各个模块就可以由不同的团队分别开发。这在大型项目中必定会发生,各个项目子团队 可以负责不同模块的交付。 最后,将一个应用程序模块化,可以帮助识别正在使用依赖类库的哪个版本,以便协 调大型项目中的类库依赖。 运行时与编译时 无论在编译时还是运行时,Java的classpath都是扁平的。换句话说,应用程序可以看 到classpath上的所有类,而不管其顺序如何(如果没有重复,是这样;否则,总是找最 前面的)。这就使Java动态链接成为可能:一个处于classpath前面的已装载类,不需要 解析其所引用的可能处于 classpath后面的那些类,直到确实需要他们为止。 如果所使用的接口实现到运行时才能清楚,通常使用这种方法。例如,一个SQL工具可 以依赖普通JDBC包来编译,而运行时(可以有附加配置信息)可以实例化适当的JDBC驱动 。这通常是在运行时将类名(实现了预定义的工厂接口或抽象类)提供给Class.forName 查找来实现。如果指定的类不存在(或者由于其他原因不能加载),则会产生一个错误。 因此,模块的编译时classpath可能会与运行时classpath有些微妙的差别。此外,每 个模块通常都是独立编译的(模块A可能是用模块C 1.1 来编译的,而模块B则可能是用模 块C 1.2 来编译的),而另一方面,在运行时则是使用单一的路径(在本例中,即可能是 模块C的1.1版本,也可能是1.2版本)。这就会导致依赖地狱(Dependency Hell),特别 当它是这些依赖传递的末尾时更是这样。不过,像Maven和Ivy这样的构建系统可以让模块 化特性对开发者是可见的,甚至对最终用户也是可见的。 Java有一个非常好的底层特性,叫做ClassLoader,它可以让运行时路径分得更开。通 常情况下,所有类都是由系统ClassLoader装载的;可是有些系统使用不同的ClassLoader 将其运行时空间进行了划分。Tomacat(或者其他Servlet引擎)就是一个很好的例子,每个 Web应用都有一个ClassLoader。这样Web应用就不必去管(无论有意与否)在同一JVM中其 他Web应用所定义的类。 这种方式下,每个Web应用都用自己的ClassLoader装载类,这样一个(本地)Web应用 实现装载的类不会与其他Web应用实现相冲突。但这就要 求对任何ClassLoader链,类空 间都是一致的;这意味着在同一时刻,你的VM可以同时从两个不同的Classloader中各自 装载一个Util.class,只要这两个ClassLoader互相不可见。(这也是为什么Servlet引擎 具有无需重启即可重新部署的能力;扔掉了一个ClassLoader,你也就扔掉了其引用类, 让老版本符合垃圾回收的条件——然后让Servlet引擎创建一个新的ClassLoader并在运行 时中重新部署应用类的新版本。) 模块化Java简介(2)时间:2011-03-25 infoq Alex Blewitt 译:宋玮再谈模块 构建一个模块化系统实际上是把系统划分成(有可能)可重用模块的过程,并使模块 间耦合最小化。同时,其也是一个减少模块需求耦合的过程:例如,Eclipse IDE许多 plugin对GUI和非GUI组件(如jdt.ui和jdt.core)的依赖是分开的,这样就可以在IDE环 境之外使用这些 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |