实用数据绑定

谁在使用这个东西,结果如何?

在应用程序中有效地插入数据绑定框架

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: 实用数据绑定

敬请期待该系列的后续内容。

此内容是该系列的一部分:实用数据绑定

敬请期待该系列的后续内容。

一直阅读本专栏的读者可能希望看到关于 JaxMe 讨论的第三部分。正如您还记得的那样,我将介绍如何使用 JaxMe 在数据库中插入和检索数据,以及如何对基本数据绑定设施实现 JaxMe 的其他改进。

这些内容我仍将介绍,但要推迟到下一期。现在,我想花点时间探讨邮件中经常出现的一些问题,当然,这些问题也是有关数据绑定的。请继续阅读我们的期刊,下一次我们将接着讨论 JaxMe。

数据绑定陷阱

虽然从具体的实现来看,前几篇文章很有用(希望如此),但我的目标是让这些文章真正实用。通过阅读书籍和杂志的内容,我不禁怀疑这些作者是否真正 使用过他们所讨论的东西。我是说,他们关于 API 的说明完全正确,从技术上说完全没有任何错误 —— 但是把车钥匙交给四岁的孩子从技术上说也没有错误。仅仅告诉他们如何启动就让他们去开车,行吗?当然不行!

我注重的不仅仅是 API 的说明,还有关于 API 最佳使用方法的信息。它什么时候工作得最好?什么情况下会陷入麻烦而破坏您的应用程序?或者更具体地说,什么情况下不值得您花费时间和精力在应用程序框架中引入新的 API?这就是我所关心并且要阐明的问题,同时假设您也关心这些问题。

因此我想从数据绑定中那些可能令您感到吃惊的方面谈起。多数问题并不是特定于 API 的(也有例外),而是适用于所有的数据绑定实现。这都是人们在使用数据绑定 API 时经常遇到的问题,其实,很多问题都适用于 所有新的、优秀的 API。

数据绑定不是时尚

对于 任何新的、令人激动的 API,人们最常犯的一个错误就是将它与时尚混为一谈。这常常表现为两种典型谬误:

  • 没有认真地思考和测试就引入一种 API。
  • 所有可能的任务中都使用一种 API。

这些都是错误的观念,原因很多。比方说第一个问题,当出现一种新的、看来很有帮助的 API 时,很多开发人员往往忽略添加新技术所需要的常规步骤。比如,没有经过漫长的讨论会、数以吨计的计划和大量的深思熟虑,您不会轻易地从 JDBC 转移到 EJB。同理,兴致所至就匆匆甩掉 SAX 和 DOM 代码,取而代之以 JAXB 或者 JaxMe(或者 Coins、Zeus、XMLBeans 等),也是极其不负责任的。

但是令人吃惊的是,很多开发人员恰恰就是这样做的。SAX 编码很令人痛苦,回调不是很符合面向对象的思路,熟练掌握它又需要花很长的时间。DOM 易于使用(尽管有时候存在一些不必要的麻烦,比如提取元素中的文本),但它可能变得很庞大,占用很多内存。但是,没有理由仅仅因为数据绑定是市面上最新的 XML 相关技术就把其他 API 扔掉。要花点时间考察新技术。阅读像本文这样的文章,演练示例代码,要谨慎从事。这样做可能慢一些,但是您可以省掉很多麻烦。

另一种诱惑是 到处使用新技术。换句话说(使用数据绑定 API 这个具体的例子),不要假设您的代码每次处理 XML 都要使用数据绑定。这种天真的、过于单纯的做法,几乎注定会在长期的运行中损害您的应用程序。比方说,如果拥有一些私有的 Perl 脚本,能够很好地读取 XML,就没有必要增加转移到数据绑定的开销,这种情况下,没有必要舍弃原有的脚本。保留精力解决那些 工作以及应该工作的任务。

标准并不总是最好的

我知道这样说会受到各种各样的抨击,但我还是要这样说:坚持基于标准的解决方案并不一定是最好的。现在,人们更清楚地认识到这一点,Sun 把所有东西都放到了 Java 技术、他们的 JSR 和 API 中,我不想批评他们这样的做法。我只是想说, Sun 签署并不是这一技术的终结,也不是最要紧的事情。如果签署是最重要的,那么就不会有人关心(比方说)Struts、Spring 或者 Hibernate 了。但人们 确实关心这些东西,因为它们 有用。这些技术都不是标准,但它们都在成千上万的应用程序中发挥着重要作用。

当然,这并不是说要您走另一个极端 —— 不要仅仅因为它 标准就逃避。我和其他人一样赞成使用开放源代码,事实上可能比他们更赞成,但有些时候我更倾向于 Sun 的解决方案,而不是开放源代码项目。要选择最适合任务的工具,不论它是什么(或者与谁有关联)。对于某个应用程序,JAXB(来自 Sun)可能正是它所需要的;如果您痛恨 JAXB,那么可以选择 JaxMe(开放源代码);也可以完全脱离规范,使用 Quick 或者 XMLbeans 之类的东西。选择权在您自己。

标准 可能是最佳选择

我知道,您可能会想“不是刚说过标准一文不值吗?”——不,我只是想说标准不是让您摒弃其他选择的王牌。但是标准有标准的好处,下面是它最主要的两个好处(至少照我看来):

  • (至少)能够在某种程度上保证稳定性和一致性。
  • (至少)在一定程度上保证跨平台的兼容性。

应该注意的是,这里都加上了 至少两个字。这些因素都应该考虑,但是除非要考察核心 JDK 的特性(像普通表达式或者正则表达式),否则这类保证不是很有必要。但它们也很重要,下面将分别进行说明。

首先,标准就是标准。它是一套确定的规则,因此您可以依靠它。如果使用遵循标准的 API,您能获得一些好处。比如,只要您的 JSP 页面也兼容 JSP,您就不需要担心 JSP 兼容的容器能否正确解释这些页面。如果出现错误,就存在一个缺陷,但该缺陷应该(大概)能很快得以修正。与 没有基于标准的项目经常遇到的情况不同,维护基于标准的项目没有太大的障碍。比方说,JAXB 代码能够用于 JAXB 兼容的 API,如 JAXB 参考实现和 JaxMe。(可能需要修改一两行代码,但也仅此而已。)当然,这不是需要考虑的惟一问题,但是,具有某种程度的稳定性、能够预期某些行为很重要。如果遇到多疑的经理,您会发现这一点 特别突出。

其次,当使用标准时,特别是使用标准的实现时,就有更多的机会把代码快速转移到其他平台、机器和开发环境中。比如,如果要部署基于 XMLBeans 的应用程序,当然需要保证目标环境中有您需要的 XMLBeans JAR 文件。虽然这样做很普遍,但是当需要与其他公司合作,而不仅仅是部署应用程序时,事情就会复杂得多。

比方说,假设您的数据绑定代码是基于非标准项目的,如 Quick 或者 Castor,您已经编好了代码,写好了 XML,创建了数据绑定 API 所使用的格式,并准备把生成的 XML 发送给其他某个合作公司。当然,他们使用了别的某种 API(不管是否基于标准都无关紧要),因此不能按照同样的方式解释您发送的 XML,尽管您费了很大的力气,但还是没有成功。这就是传统的契约问题:如何保证通信链的两端采用一致的方式处理数据?标准化的 API(如 JAXB)可以帮助您避免这种困境。

更好的方法

之前,我一直在进行负面说教,现在来谈一谈使用这些技术的 正确方法。这里所说的事情都很简单,也没有特别好的见解,但是却能给应用程序的运行和维护带来很多变化。

您还应该知道的是,这些并不是很全面的解决方案,您可能会发现某些情况下,其中的一两个观点也不是很适合您的体系结构。其他情况下,您可能也不认为这些观点有什么价值。这些都是一些合理的想法和实践中得来的教训,关键是要花大量的时间考虑您的基础设施。不要简单地采用一种解决方案或者技术,相反,要仔细地规划和评估每个决策带来的后果。不仅您的老板会赞成这样做,您也会发现您不再经常需要在办公室里一直干到清晨两点。

关键是抽象

在本专栏和其他文章中,我都反复强调了抽象这一词。抽象是如此之重要,我认为有必要再提一提。简言之,任何东西 —— 再多么巧妙的编程设计 —— 都比不上模块化设计。如果要使用数据绑定,不要假设 总是使用数据绑定。相反,要抽象出您希望实现的功能。比如,数据绑定常用于从存储介质读写数据。换句话说,它主要和 数据持久性有关。因此不要想 让应用程序的其他部分进行数据绑定,而是应该考虑 应用程序中处理持久性的那一部分

这两种方法的差异经彻底改变了思考应用程序设计的方式。如果从数据绑定的角度考虑问题,直接调用数据绑定 API 的各种代码就会散布到应用程序的各处(无论是 JAXB、Zeus 还是其他 API)。这样的话,如果需要改变所用的 API,或者从数据绑定转移到 JDO 这类技术或其他的新技术,都必须对应用程序代码作 大量的修改。这太糟了。

另一方面,假设仅仅将其看作一种持久数据的 API。如果持有这种观点,您可能认识到需要一种更小的应用程序专用 API。它可能叫作 writeAddress(Address address)loadUserCredentials(int userID) 。您的应用程序需要调用的就是 这种API。然后,这个外壳 API 再使用某种技术(如数据绑定)完成这项任务。如果要使用另一个项目或技术,只需要修改外壳类即可,外壳类通常都在一两个包内,这样,应用程序会更加健壮。应用程序的其他部分仍然可以欢快地运行,调用同样的 API 时,完全不用担心加载和存储是如何完成的。这 就是好的设计。

测试、测试、再测试

我知道,时至今日,测试这个词已不再流行,但它仍然很重要。我工作过的上一家软件公司中就单独有一个部门从事测试。这伙人能破坏任何东西!但是经过测试后出来的应用程序基本上是不可摧毁的。其价值是无法度量的,发布一个产品额外付出的时间、努力和金钱是完全值得的。

所幸的是,由于极限编程和敏捷开发这些概念的出现,即使没有整个团队的人来锤炼代码,在很大程度上,您也能获得同样的收益。当然,我们假设您正在实际 采用这类方法进行开发。显然,时间和文章篇幅都不允许我详细介绍团队开发、测试驱动的开发、用例 和 JUnit 之类的东西。但是这方面有大量的参考资料,您可以自己去寻找。

如果您不能确定所做的测试是否足够,这里有一条很好的经验法则:如果任何测试都没有失败,那么肯定是测试工作没做好。换句话说,如果编写模块,然后进行第一次测试,没有出现错误,那么我敢说您做的测试还不够严格。当然,您可能只匆匆地写一些代码就实现了测试,但这种情况毕竟很少(Brunson 确实曾经靠 10 次平局赢过 两次世界锦标赛)。要进行广泛的各种各样的测试(甚至在开始编写要测试的代码之前),确保所有要求的功能都能测试到。测试失败的确很令人苦恼,但是,在正式推出产品的时候,确信自己不用因为明显的缺陷而需要返工也很令人欣慰。

设想非常笨和非常聪明的用户会怎么做

还有一点,我称之为对等思考。这是基本做法,与测试有一些关系,但是也值得单独提出来。记不起来曾经有多少次我认为我已经完成了一个应用程序模块 —— 主要是因为我每次使用的时候都很成功,但是一提交,就马上发现了数以百计的小问题。坦白地说,花了很长时间我才认识到,并不是所有的用户都和我一样!

一旦明白了这一点,我就开始做两方面的假设:

  • 我将遇到一个非常迟钝的用户,他会尝试所有可能的方法破坏我的应用程序,以荒谬的方式把事情搞得一团糟,根本不做任何思考。
  • 我将遇到一个非常聪明的用户,他们会想出间接、奇特的方式处理问题,但最终可能因为想打破传统或者意外而把事情弄糟。

这两种假设都是合情合理的,都有必要加以解决。一种方法是再回过头来进行测试,但是测试无法逮住滥用的用户,不管他们是否有意这样做。一旦完成了所有的测试,我建议您试一试 野蛮测试。就是像少数对您的应用程序一无所知的人那样去尝试。这些人对计算机了解得越少越好,您会发现一些最奇怪的行事方法,他们还会破坏掉您的模块。但是这样做可以在损失您的金钱和信誉 之前纠正问题。

然后还要进行某种 黑客式的测试。找一个认识的安全高手,请他攻击您的应用程序。您可能不知道他们是怎么做的,但他们一般都会攻入您的应用程序。现在还要请那位黑客告诉您问题所在,填补漏洞,然后一路笑着去银行就行了。是不是很简单?付出的时间和精力是完全值得的。

结束语

虽然本文暂时中断了关于 JaxMe 的讨论,但我还是希望本文的内容能够为您带来帮助。这些关于数据绑定使用的问题和建议不是我坐而论道空想出来的,而是结合了很多读者和留言者在邮件中提出的问题。我从中选择了一些我认为值得详细讨论一番的、反复出现的问题。

我没有讨论所有可能的问题和情况。虽然下一期将继续回到 JaxMe,但我愿意收到您的用例。如果有什么想法或者问题,请发邮件给我,您的问题也许会在下一篇关于陷阱和建议的文章中出现,我希望您已经学到新的东西,改进了代码,痛苦减轻了一些。和往常一样,让我们下次网上再见吧!


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=XML
ArticleID=23235
ArticleTitle=实用数据绑定: 谁在使用这个东西,结果如何?
publish-date=10012004