迁移到 Nokogiri

2011 年 1 月 10 日

本网站的大部分内容,包括这个 bliki,都是使用 XML 到 HTML 的转换过程构建的。我用自己的 XML 词汇编写文章和 bliki 条目,然后将这些来源转换为您阅读的 HTML。当我从 2000 年开始的时候,我是在 XSLT 中完成的。虽然我在 XSLT 编程方面做得很好,但我得出的结论是我没有足够的受虐狂倾向,不想继续使用它。在短时间内尝试用 Ruby 在飞往班加罗尔的航班上编写 bliki 转换器后,我切换到了使用 REXML 库的 Ruby。现在是时候将这个核心库更改为 Nokogiri 了。

当我开始使用 Ruby 转换器时,Ruby 中解析 XML 的默认方法是 REXML 库。虽然它有一些怪癖,但总的来说我喜欢它。与那个时代的 Java 库相比,这个 API 当然更容易使用。但时间在流逝。REXML 是一个 Ruby 库,因此与基于 libxml 的库相比速度较慢。其他库也出现了,它们提供了更友好的 API 来使用。

如今,XML 解析的流行选择似乎是 Nokogiri。因此,在过去几个月里,我尝试了它来完成一些转换任务,并且越来越喜欢它。它很快成为我新转换任务的首选。但这仍然留下了最大的问题,我应该用 Nokogiri 替换 REXML 用于我的核心转换吗?

直到最近,我的生活一直被 DSL 书所主导,所以我没有考虑过对我的网站生成代码进行任何严肃的工作。一旦完成,我的首要任务是重新设计网站的外观和感觉,并引入指南页面。这不需要对现有的 Ruby 代码进行太多修改,所以我保留了原样。但我的下一步需要对该代码进行更严肃的重构,这让我更加考虑用 Nokogiri 替换。

事实上,我决定首先解决这个问题,有两个原因。一是大部分转换代码都涉及对 XML 的操作,我想使用 Nokogiri 的 API 来完成这些操作。二是我的主要功能测试是重建网站并将结果与发布版本进行比较。Nokogiri 的速度优势(10 秒对 1 分钟)在我进行这项操作时变得更加重要。

进行更改

在主要进行 XML 处理的程序中替换 XML 库通常被认为是一项艰巨的任务。代码中到处都是 REXML 调用,因此这是一个非常全局性的更改。由于我是唯一的程序员,我可以比与团队合作时更随意,但我仍然遵循与与其他人合作时相同的习惯。

基本计划分为三个步骤

  • 在我的代码和 REXML 之间引入一个隔离层。这样,我的所有转换代码都会调用这个隔离层,然后隔离层将调用传递给 REXML。在这个阶段,隔离层的接口与 REXML 非常接近。
  • 创建隔离层的替代实现,将相同的调用传递给 Nokogiri。一旦完成,我就可以完全使用 Nokogiri 构建网站。
  • 调整接口和应用程序代码,将其从 REXML 风格更改为 Nokogiri 风格。最后删除隔离层。

我使用这种方法来使步骤更小。一次性切换到 Nokogiri 变化太大,相反,我可以逐步实现它,同时我的网站仍然可以使用 REXML 版本构建,直到 Nokogiri 实现完成。如果我和其他人一起工作,这将更加重要,因为我需要让他们在进行手术时构建新功能。这样,我就可以在构建隔离层时逐渐让他们迁移到隔离层。

有人主张保留隔离层,实际上将其变成一个反腐败层。如果我想使用与 Nokogiri 不同的 API,这将是一个好主意。我没有这样做,因为我主动想使用 Nokogiri 的 API。当然,这意味着如果我更改库,我将不得不重新构建它,但我宁愿付出这个代价,也不愿现在付出处理不必要层的代价。