编译和部署Java应用需要使用包括特定平台的脚本、Make文件、不同的IDE以及手工操作等组成的大杂烩。现在,几乎所有的开源Java项目都在使用Ant,许多公司的开发项目也在使用Ant。Ant的大量使用,也自然带来了对总结Ant最佳实践的迫切需求。
1. 采用一致的编码规范
Ant用户不管是喜欢还是痛恨XML构建文件的语法,都愿意跳进这一迷人的争论中。让我们先看一些保持XML构建文件简洁的方法。
首先,也是最重要的,化费时间格式化你的XML让它看上去很清晰。不过XML是否美观,Ant都可以工作。但是丑陋的XML很难读懂。倘若你在任务之间留出空行,有规则的缩进,每行文字不超过90列,那么XML令人惊讶的易读。再加上好的编辑器或IDE高亮相应的语句,你就不会有如何阅读的麻烦。
同样,精选有意义明确、容易读懂的词汇来命名任务和属性。比如,dir.reports就比rpts好。并不需要特定的编码规范,只要有一种规范并坚持使用就好。
2. 将build.xml 放在项目根目录中
Ant构建文件build.xml可以放在如何位置,但是放在项目顶层目录中可以保持项目简洁。这是最普遍的规范,使开发者能够在根目录找到它。同时,也能够容易了解项目中不同目录之间的逻辑关系。以下是一个典型的项目层次:
[root dir]
| build.xml
+--src
+--lib (包含第三方 JAR包)
+--build (由 build任务生成)
+--dist (由 build任务生成)
当build.xml在顶级目录时,倘若你在项目某个子目录中,只要输入:ant -find compile 命令,不需要改变工作目录就能够以命令行方式编译代码。参数-find告诉Ant寻找存在于上级目录中的build.xml并执行。
3. 使用单一构建文件
有人喜欢将一个大项目分解到几个小的构建文件,每个构建文件分担整个构建过程的一小部分工作。但是应该认识到,将构建文件分割会增加对整个构建过程的理解难度。要注意在单一构建文件能够清楚表现构建层次的情况下,不要过工程化(over-engineer)。
即使你把项目划分为多个构建文件,也应使程序员能够在项目根目录下找到核心build.xml。尽管该文件只是将实际构建工作委派给下级构建文件,也应保证该文件可用。
4. 提供良好的帮助说明
应尽量使构建文件自文档化。增加任务描述是最简单的方法。当你输入ant -projecthelp时,你就可以看到带有描述的任务清单。比如,你可以这样定义任务:
<target name="compile"
description="Compiles code, output goes to the build dir.">
最简单的规则是对所有你希望程序员通过命令行直接调用的任务都加上描述。对于一般用来执行中间处理过程的内部任务,比如生成代码或建立输出目录等,就无法使用描述属性。
这时,可以通过在构建文件中加入XML注释来处理。或者专门定义一个help任务,当程序员输入ant help时来显示详细的使用说明。
<target name="help"
description="Display detailed usage information">
<echo>Detailed help...</echo>
</target>
5. 提供清空任务
每个构建文件都应包含一个清空任务,删除所有生成的文件和目录,使系统回到构建文件执行前的初始状态。执行清空任务后还存在的文件应处在版本控制系统的管理下。
比如:
<target name="clean"
description="Destroys all generated files and dirs.">
<delete dir="${dir.build}"/>
<delete dir="${dir.dist}"/>
</target>
除非是在产生整个系统版本的特殊任务中,否则不要自动调用clean任务。当程序员仅仅执行编译任务或其他任务时,他们不需要构建文件事先执行即令人讨厌有没有必要的清空任务。要相信程序员能够确定何时需要清空所有文件。
6. 使用ANT管理任务从属关系
假设你的应用由Swing GUI组件、Web界面、EJB层和公共应用代码组成。在大型系统中,你需要清晰地定义Java包属于系统的哪一层。否则如何一点修改都要重新编译成千上百个文件。任务从属关系管理差会导致过度复杂而脆弱的系统。改变GUI面板的设计不应造成Servlet和EJB的重编译。
当系统变得庞大后,稍不注意就可能将依赖于客户端的代码引入到服务端。这是因为IDE在编译文件时使用单一的classpath。Ant让你更有效地控制构建活动。
设计你的构建文件编译大型项目的步骤:首先,编译公共应用代码,将编译结果打成JAR包文件。然后,编译上一层的项目代码,编译时依靠第一步产生的JAR文件。不断重复这一过程,直到最高层的代码编译完成。
分步构建强化了任务从属关系管理。如果你工作在底层Java框架上,引用高层的GUI模板组件,这时代码不需要编译。这是由于构建文件在编译底层框架时,在源路径中没有包含高层GUI面板组件的代码。
7. 定义并重用文件路径
如果文件路径在一个地方集中定义,并在整个构建文件中得到重用,那么构建文件更易于理解。以下是这样做的一个例子:
<project name="sample" default="compile" basedir=".">
<path id="classpath.common">
<pathelement location="${jdom.jar.withpath}"/>
...etc
</path>
<path id="classpath.client">
<pathelement location="${guistuff.jar.withpath}"/>
<pathelement location="${another.jar.withpath}"/>
<!-- reuse the common classpath -->
<path refid="classpath.common"/>
</path>
<target name="compile.common" depends="prepare">
<javac destdir="${dir.build}" srcdir="${dir.src}">
<classpath refid="classpath.common"/>
<include name="com/oreilly/common/**"/>
</javac>
</target>
</project>
当项目不断增长,构建日益复杂时,这一技术越发体现出其价值。你可能为编译不同层次的应用定义各自的文件路径,比如运行单元测试的、运行应用程序的、运行Xdoclet的、生成JavaDocs的等等不同路径。这种组件化路径定义的方法比为每个任务单独定义路径要优越得多。否则,很容易丢失任务任务从属关系的轨迹。
8. 定义恰当的任务参数关系
假设dist任务从属于jar任务,那么哪个任务从属于compile任务,哪个任务从属于prepare任务呢?Ant构建文件最终定义了任务的从属关系图,它必须被仔细地定义和维护。
应该定期检查任务的从属关系以保证构建工作得到正确执行。大的构建文件随着时间推移趋向于增加更多的任务,所以到最后由于不必要的从属关系导致构建工作非常困难。比如,你可能发现在程序员只是需要编译一些没有使用EJB的GUI代码时,重新生成EJB代码。
以“优化”的名义忽略任务的从属关系是另一种常见的错误。这种错误迫使程序员为了得到恰当的结果必须记住并按照特定的顺序调用一串任务。更好的做法是:提供描述清晰的公共任务,这些任务包含正确的任务从属关系;另外提供一套“专家”任务让你能够手工执行个别的构建步骤,这些任务不提供完整的构建过程,但是让那些专家在快速而恼人的编码期间跳过某些步骤
9.使用配置属性
任何需要配置或可能发生变化的信息都应作为Ant属性定义下来。对于在构建文件中多次出现的值也同样处理。属性既可以在构建文件头部定义,也可以为了更好的灵活性而在单独的属性文件中定义。以下是在构建文件中定义属性的样式:
<project name="sample" default="compile" basedir=".">
<property name="dir.build" value="build"/>
<property name="dir.src" value="src"/>
<property name="jdom.home" value="../java-tools/jdom-b8"/>
<property name="jdom.jar" value="jdom.jar"/>
<property name="jdom.jar.withpath"
value="${jdom.home}/build/${jdom.jar}"/>
etc...
</project>
或者你可以使用属性文件:
<project name="sample" default="compile" basedir=".">
<property file="sample.properties"/>
etc...
</project>
在属性文件 sample.properties中:
dir.build=build
dir.src=src
jdom.home=../java-tools/jdom-b8
jdom.jar=jdom.jar
jdom.jar.withpath=${jdom.home}/build/${jdom.jar}
用一个独立的文件定义属性是有好处的,它可以清晰地定义构建中的可配置部分。另外,在开发者工作在不同操作系统的情况下,你可以在不同的平台上提供该文件的不同版本。
10. 保持构建过程独立
为了最大限度的扩展性,不要应用外部路径和库文件。最重要的是不要依赖于程序员的CLASSPATH设置。取而代之的是,在构建文件中使用相对路径并定义自己的路径。如果你引用了绝对路径如C:\java\tools,其他开发者未必使用与你相同的目录结构,所以就无法使用你的构建文件
如果你部署开发源码项目,应该提供包括所有需要的JAR文件的发行版本,当然是在遵守许可协议的基础上。对于内部项目,相关的JAR文件都应在版本控制系统的管理中,并捡出到大家都知道的位置。
当你不得不应用外部路径时,应将路径定义为属性。使程序员能够涌适合他们自己的机器的参数重载这些属性。你也可以使用以下语法引用环
分享到:
相关推荐
在【Ant】这个压缩包文件中,可能包含了实现蚂蚁算法的源代码、实验数据、演示案例或者相关文档,帮助学习者理解算法原理并进行实践操作。通过这个作业,学生能够了解到如何运用编程语言(如Python、Java等)来模拟...
贪吃蛇游戏的实现主要会集中在几个关键的类中,例如游戏主类(可能命名为`SnakeGame`或类似),这个类负责管理游戏状态,控制蛇的移动,并处理用户输入。另一个重要的类可能是`GameView`,它继承自Android的`...
具体到代码结构,可能包含以下几个关键部分: 1. 初始化:设置蚂蚁数量、迭代次数、信息素蒸发率、启发式信息权重等参数。 2. 蚂蚁路径选择:每只蚂蚁根据当前的信息素浓度和启发式信息选择下一个节点。 3. 更新信息...
【标签】"java 源码 经典" 暗示了这个项目在 Java 开发者社区中的地位,可能是一个被广泛讨论和学习的经典案例。Java 源码代表了项目的编程语言,适合 Java 学习者研究;"经典"则表明这个项目在教学或实践中有着重要...
总的来说,这个压缩包提供了一个实践性的案例,让学习者能够亲手尝试用MATLAB实现蚁群算法解决TSP问题,从而更好地掌握这种算法的原理和应用。对于研究优化问题、图论或者MATLAB编程的学习者来说,这是一个非常有...
在这个案例中,我们有以下几个主要的Matlab源文件: 1. `main.m`:这是主程序文件,它应该包含了初始化参数、蚁群设置、迭代过程以及结果显示等功能。 2. `drawTSP10.m` 和 `drawTSP.m`:这两个文件可能是用于绘制...
在提供的压缩包中,主要有以下几个文件: 1. ACOTSP.doc:这可能是算法的理论介绍或者使用指南,详细解释了蚁群算法的基本原理,以及如何将其应用于TSP问题。它可能包含算法的参数设置、迭代过程和结果分析等内容。...
在描述中提到的链接指向了一个博客文章,虽然具体内容未提供,但通常这类资源会包含书中的实践案例、读者评论或作者的额外见解。因此,我们可以从中推测该书不仅涵盖理论,还可能涉及到实际应用和经验分享。 标签...
在MATLAB中实现ACO,我们需要以下几个关键步骤: 1. 初始化:设定蚂蚁数量、信息素蒸发率、信息素更新强度等参数,并随机生成每只蚂蚁的初始路径。 2. 汇总路径:每只蚂蚁根据当前路径上的信息素浓度和启发式信息...
在本案例中,遗传算法、禁忌搜索、模拟退火和蚁群算法被用来解决这个问题,这些都是在人工智能领域广泛应用的全局优化技术。 首先,让我们详细探讨一下这些算法: 1. 遗传算法(Genetic Algorithm): 遗传算法是...
在这个案例中,MATLAB程序利用了“蚁群算法”(Ant Colony Optimization, ACO)来寻找旅行商问题的近似最优解。蚁群算法是模拟自然界中蚂蚁寻找食物路径行为的一种优化算法,它通过迭代过程逐步优化解决方案,具有...
`ACA_TSP.m`的主要内容可能包括以下几个部分: 1. **初始化**:设定参数如蚂蚁数量、信息素蒸发率、信息素更新规则等。 2. **城市坐标读取**:读取`Cities.txt`文件,将城市坐标转化为邻接矩阵或其他数据结构。 3. *...
在`ACO.py`这个源代码文件中,我们可以预期看到以下几个关键部分: 1. **模型定义**:首先,蚁群算法会定义一个模型,包括城市的位置、蚂蚁的数量、信息素的更新规则以及蒸发率等参数。这些参数对算法的性能有直接...
通常,一个J2ME游戏项目可能会包含以下几个部分: 1. **源代码**:Java源文件(.java),包含了游戏的主要逻辑、场景、角色等类。 2. **资源文件**:如图片、音频、配置文件等,尽管描述中指出只含源码,但通常游戏...
在MATLAB中实现蚁群算法解决TSP,主要涉及以下几个步骤: 1. **初始化**:随机生成每只蚂蚁的路径,设置初始的信息素浓度和启发式信息。 2. **蚂蚁路径构造**:每只蚂蚁基于当前信息素浓度和启发式信息(如距离)...
【基于蚁群算法的TSP路线规划问题MATLAB仿真】是一种使用模拟生物群体行为的算法——蚁群优化算法(Ant Colony Optimization, ACO)来解决旅行商问题(Traveling Salesman Problem, TSP)的实践案例。在MATLAB环境下...
在这个程序中,主要包含以下几个关键步骤: 1. 初始化:设定蚂蚁数量、信息素蒸发率、启发式因子等参数,并随机生成每只蚂蚁的初始路径。 2. 循环迭代:每只蚂蚁依据信息素浓度和启发式信息选择下一个城市,形成...
在"MainFrame.java"中,我们可以预期看到以下几个关键部分: 1. **初始化**:设置蚂蚁数量、信息素蒸发率、启发式信息权重等参数,以及构建城市和距离矩阵。 2. **蚂蚁循环**:每个蚂蚁根据信息素浓度和启发式信息...
5. **构建复杂的插件项目**:提供实际案例分析,帮助读者掌握如何构建大型、复杂的Eclipse插件项目。 6. **性能优化**:分享提升Eclipse插件性能的最佳实践,包括内存管理、加载时间优化等方面的策略。 7. **国际化...
系统的设计和开发过程中,会涉及到以下几个关键知识点: 1. **RESTful API设计**:为了实现前后端分离,系统需要提供清晰、规范的RESTful接口,以便小程序或者其他前端调用,完成数据交换。 2. **安全控制**:包括...