当您在 Java 中使用正则表达式时,依赖某一具体 regexp 库通常不是个好 主意。如果使用抽象层,您可以在不同 regexp 库之间切换,降低您的代码与特 定库之间的耦合,并能选择哪个库最适合您的需要。如果您正在考虑在下一个项 目中使用 Java regexp 库,软件开发人员 Jose San Leandro Armendariz 将向 您演示如何使代码独立于所选择的具体库。并让您进一步了解 regexp 及其工作 原理,随后还提供了一些练习。
简介
尽管您可能认为编写需要分析文本的 Java 应用程序是一项简单任务,但象 许多事情一样,它会很快变得复杂起来。那的确是我在编写代码以解析 HTML 页 面时的经验。开始的时候,我偶尔会使用 Perl5 正则表达式(regexp)。但是 ,由于某些原因(稍后说明),我后来常常使用它们。
背景知识
在我的经验中,大多数 Java 开发人员都需要解析某种文本。通常,这意味 着他们最初要花一些时间使用象 indexOf 或 substring 那样的与 Java 字符串 相关的函数或方法,并且希望输入格式永远不变。但是,如果输入格式改变,那 么用于读取新格式的代码维护起来就会变得更复杂、更困难。最后,代码可能需 要支持自动换行(word wrapping)、区分大小写等。
由于逻辑变得更加复杂,所以维护也变得很困难。因为任何更改都可能产生 副作用并使文本解析器的其它部分停止工作,所以开发人员需要时间修正这些小 错误。
有一定 Perl 经验的开发人员可能也有过使用正则表达式的经验。如果够幸 运(或优秀)的话,这位开发人员能够说服团队其余的人(或至少是团队领导) 使用这项技术。新的方法将取消编写用来调用 String 方法的多行代码,它意味 着将解析器逻辑的核心委托出去,并替换为 regexp 库。
接受了有 Perl5 经验的开发人员的建议后,团队必须选择哪个 regex 实现 最适合他们的项目。然后他们需要学习如何使用它。
在简要地研究了从因特网上找到的众多可选方案后,假设团队决定从人们更 熟悉的库中选择一个使用,如属于 Jakarta项目的 Oro。接下来,对解析器进行 较大程度地重构或几乎重新编写,并且解析器最终使用了 Oro 的类,如 Perl5Compiler 、 Perl5Matcher 等。
这一决定的后果很明显:
代码与 Jakarta Oro 的类紧密地耦合在一起。
团队承担了风险,因为不知道非功能性需求(如性能或线程模型)是否将得 到满足。
团队已花费时间和财力来学习并重新编写代码,以使它使用 regexp 库。如 果他们的决定是错误的并且选择了新的库,则这一工作在成本上将不会有很大区 别,因为将需要再次重新编写代码。
即使库工作正常,如果他们决定应该迁移到全新的库(例如,包括在 JDK 1.4 中的库),怎么办?
去耦的好处
有没有办法使团队知道哪个实现最适合他们的需要呢(不仅现在能将来也能 )?让我们试着寻找答案。
避免依赖任何特定的实现
前面的情形在软件工程中十分常见。在有些情况中,这样的情形会导致较大 的投资和较长的延期。当不了解所有后果就作出决定而且决策制定人不太走运或 缺乏必需的经验时,就常常会发生这种情况。