没有清理
没有严格减少所有底层假设的构建无疑是一颗定时炸弹。例如,如果构建没有避免一些简单的假设,例如会去掉用陈旧的数据生成的二进制文件,那么前一次构建遗留下来的文件就会引起错误。或者,正是由于前一次构建留下的文件,构建竟然得以"成功",这种情况更糟糕。
幸运的是,这个问题的解决办法很直观:只需删除任何之前的构建留下的所有目录和文件,就可以很容易地消除假设。这个简单的动作就可以减少假设,保证构建的成功或失败都是正确的。清单 5 演示了通过使用 delete Ant 任务删除之前的构建所使用的所有文件或目录,从而清理构建环境的一个例子:
清单 5. 事先清理
<target name="clean"> <delete dir="${logs.dir}" quiet="true" failonerror="false"/> <delete dir="${build.dir}" quiet="true" failonerror="false"/> <delete dir="${reports.dir}" quiet="true" failonerror="false"/> <delete file="cobertura.ser" quiet="true" failonerror="false"/> </target> |
众所周知,旧的构建遗留下来的文件会导致很多不必要的麻烦。为了自己的方便,在运行一个构建之前,务必先删除构建所创建的任何工件。
硬编码的臭味
复制-粘贴式的编程有碍重用,将值进行硬编码又何尝不是呢。当构建脚本包含硬编码的值时,如果某个方面需要修改,那么就需要在多个地方修改那个值。更糟糕的是,很可能会忽略了某个地方而没有改那个值,从而引起与不匹配的值相关的错误,这种错误是很隐蔽的。而且,如果相信我的建议,选择使用多个构建脚本,那么硬编码的值将可能会成为构建维护中最终的挑战。在这一点上也请相信我!
例如,在清单 6 中,run-simian 任务有很多硬编码的路径和值,即 _reports 目录:
清单 6. 硬编码的值
<target name="run-simian"> <taskdef resource="simiantask.properties" classpath="simian.classpath" classpathref="simian.classpath" /> <delete dir="./_reports" quiet="true" /> <mkdir dir="./_reports" /> <simian threshold="2" language="java" ignoreCurlyBraces="true" ignoreIdentifierCase="true" ignoreStrings="true" ignoreStringCase="true" ignoreNumbers="true" ignoreCharacters="true"> <fileset dir="${src.dir}"/> <formatter type="xml" toFile="./_reports/simian-log.xml" /> </simian> <xslt taskname="simian" in="./_reports/simian-log.xml" out="./_reports/Simian-Report.html" style="./_config/simian.xsl" /> </target> |
如果硬编码 _reports 目录,那么当我决定将 Simian 报告放到另一个目录时,就会很麻烦。而且,如果其他工具在脚本的其他地方使用这个目录,那么很可能会有人输错目录名称,导致报告显示在不同的目录中。这时可以定义一个属性值,由这个属性值指向这个目录。然后,在整个脚本中都可以引用这个属性,这意味着当需要更改的时候,只需光顾一个地方,即属性的定义。清单 7 展示了重构之后的 run-simian 任务:
清单 7. 使用属性
<target name="run-simian"> <taskdef resource="simiantask.properties" classpath="simian.classpath" classpathref="simian.classpath" /> <delete dir="${reports.simian.dir}" quiet="true" /> <mkdir dir="${reports.simian.dir}" /> <simian threshold="${simian.threshold}" language="${language.type}" ignoreCurlyBraces="true" ignoreIdentifierCase="true" ignoreStrings="true" ignoreStringCase="true" ignoreNumbers="true" ignoreCharacters="true"> <fileset dir="${src.dir}"/> <formatter type="xml" toFile="${reports.simian.dir}/${simian.log.file}" /> </simian> <xslt taskname="simian" in="${reports.simian.dir}/${simian.log.file}" out="${reports.simian.dir}/${simian.report.file}" style="${config.dir}/${simian.xsl.file}" /> </target> |