BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

采访和书摘:Jaroslav Tulach的Practical API Design

| 作者 Srini Penchikala 关注 36 他的粉丝 ,译者 沙晓兰 关注 0 他的粉丝 发布于 2009年11月17日. 估计阅读时间: 14 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

Jaroslav Tulach最近的新书—— Practical API Design的主题是软件项目的API设计。书中讨论了目前软件应用API设计的重要,谈到了决定好的API的各种因素,还谈到如何实现API框架。此外,书中汇聚了他在NetBeans IDE项目开发中构架设计的经验。Jaroslav还结合自己在开发NetBeans项目的经验,通过一些实例来说明如何使用(更重要的是,说明哪些使用方法不应当采用)Java API。

在采访中,InfoQ和Jaroslav聊到他这本新书写作的动力,也聊到一些其它方面的话题,比如说评估和确认软件的质量;敏捷和精益软件开发方法在设计API框架、构架和设计审核中的角色。

我们同时也为读者节选了Practical API Design的部分章节(大约4MB的PDF)。

InfoQ:请问,是什么激励您编写了《 Practical API Design》一书?

Jaroslav Tulach(JT):这本书的基础是过去十年中,我在NetBeans API设计和维护的工作中积累的笔记。当然,这些笔记也是在把NetBeans API知识传授给其他NetBeans开发组的时候积累的。五年前,我就开始想把这些笔记结集成书,但到真正开始着手这件事又拖了一段时间。一部分原因是我还有其它任务要完成,另一部分原因是我一直都害怕自己没法坚持完成这本书,也害怕被出版社拒绝出版。

但是2007年夏天,在一次家庭聚会上,跟我太太的表哥聊过之后,我就改变了主意。我跟他谈到自己的顾虑,他说:“你知道这本书应该写些什么,你也知道这个话题很有意思,而且你自己也是这方面的专家,那你为什么还没开始写?”

在写作这样耗时的项目里,每当我完成《Practical API Design》这本书的动力减退时,我都会想起他的这段话。刚好利用这个机会,我要再次感谢所有帮助我完成这本书的朋友。

InfoQ书中,您谈到实现模块构架( Modular Architecture)的组件注射( Component Injection)技术。像依赖注射(Dependency Injection)(DI)、面向方面编程(Aspect-Oriented Programming)(AOP),以及注解(Annotations)这样的设计理念,在常规的软件开发,尤其在API设计中能起到怎样的作用呢?

JT:我觉得把应用划分成不同的模块是非常可取的。如果模块之间都互不得知各自的存在,那就更好了。这样一来,各个独立的模块就能轻易组装成完整的应用。要把松耦合的控件组装起来,那就需要某种方式的注射。Spring风格的依赖注射就很好。java.util.ServiceLoader也很好用。书中第七章,我就专门比较了这几种方法。

曾经有段时间,大家一听到“字节码操作(bytecode manipulation)”就懵了。现在就不一样了。大家不再害怕执行那些非Java编译器所生成的字节码了。但是,你要是说直接去.class文件来处理利用那些bits,那种恐惧就又回来了。为什会这样?我觉得这是因为AOP的缘故。AOP常常会要修改字节码,但又完全不需要理解class文件的格式。实际上,AOP可以视作是操作字节码的高阶语言。尽管它的威力没有直接修改.class文件那么强大,但是对于大众来说是可行的而且通常来说更容易理解。这也正好说明了这样一条原则:好的抽象能够让任何事物更为有用。这条原则在字节码操作中有用,在API设计中一样有用。

我们在下个版本的NetBeans IDE的开发中开始引入大量的注解。基本上,我们在老的基于XML的API上定义新的注解作为facade。编译过程中,注解都经由我们的注解处理器来处理。处理的最后会生成正确(又老又复杂)的XML。我无法描述这个解决方案所带来的喜悦!我们的API突然因此变得更为出色。注册信息现在也成为Java 源代码的一部分。IDE里能自动执行代码补全。所有注册信息的正确性在编译过程中验证。基于这些经验,我强烈向所有API设计师推荐编译时的注解!

InfoQ:您在书中写到如何验证API库的质量的话题。您能否给大家阐述一下团队如何评估和核对正在编写的软件的质量?

JT:程序员公认的是设计无法由委员会来做。然而,我们没法在没有团队的情况下设计出不断扩大的系统。没有团队的工作会影响到一致性吗?会,但不绝对。很多人在独自工作的时候能保持设计的一致.今天甚至是未来的软件项目都会通过多个团队来完成设计。这种环境下要保证一致性要难得多,但不是没可能。

通常会有两种选择:要么在质量倒退发生的时候侦测到其倒退,要么在集成之前就预防这类问题的产生。我在第十六章里专门讲了这个话题。我在这一章节里讲了在审核过程中哪些方面需要核对、怎样自动核对。这样,在质量出现问题的时候我们也已有所准备。另外,这一章节还引入了一个“API审核”程序。这个程序中,NetBeans团队在集成开始之前就跟踪审核API的修改。我们因次就更不用担心会有质量倒退了。

InfoQ:敏捷、精益软件开发方法,比如SCRUM、XP和Kanban怎样帮助项目团队参与到API框架的设计和开发中去呢?

JT:问题是敏捷开发方法是否促进API框架的设计和开发,或者说把应用适当的模块化,把整个API框架划分成多个子API库能够简化敏捷开发方法的实施吗?这两个问题的答案都可能是肯定的。

API开发世界有些成熟的规则。比方说,一开始你就应该铭记你设计的API第一个版本肯定不会是完美的。而且,你应当想像一下谁会是你API的用户。两外两个基本原则是单元测试是必须的,还有你设计API的时候应当注意到它的可扩展性。

很多这种建议和敏捷开发方法的主要准则非常接近。所以,我觉得恰当的API设计和敏捷开发方法是相互促进的。

InfoQ:您能讲一下您所在的团队是如何在NetBeans开发项目中实施构架和设计审核的吗?

JT:我们有两种模式:标准审核和快速追踪审核。后者用于较小、递增、兼容、没有争议的修改。这种模式建立在“乐观锁定策略(optimistic locking strategy)”之上,也就是说,你准备一个代码修改diff文件,然后把这个文件添加到问题追踪系统(issue tracking system)中。然后,大家有一个星期的时间对这个修改发表评论和投票。如果在规定的时间内,没有任何人提出反对一件,那么这个修改会立马生效。这种模式非常适合单个方法的修改或者是在已有类库的基础上对类进行扩展。

标准审核针对的是整个新类库或者是子系统,这个审核有两轮。首先,我们审核概念。然后,如果概念被接受,那么成果会在集成到主代码库之前再审核。所有审核细节都会记录在案并发布在NetBeans网站。

InfoQ:软件构架师在创建可复用的组件类库时,应当铭记哪些最佳实践?

JT:这很难列举所有,在 Practical API Design一书中我就花了400页:)。但我们可以来看几个很有意思的问题:“你觉得API这三个字母背后包含了什么?”类的名字?也许。类的域名和方法名?也许,如果它们是public或者protected。但仅仅是这些吗?

当然不是了。你有没有想过你的应用读取的那些文件就是所谓的API?那些打开的套接字难道不是API吗?环境变量呢?本地化的消息呢?还有你代码生成的文本内容呢?所有这些都能影响应用或者类库的行为。它们都能在外部观测和使用。因此,它们都是某种意义上的API。理会这点很重要,而且要时时铭记。

InfoQ:目前经济市场情况下,软件构架师扮演的是什么角色?

JT:这个问题很难。概括来说就是试着提供市场所需。但我觉得没有人真的知道市场需要什么。除非。。。软件开发中的某个问题直接关系到大的变动,也就是说,这种情况下你的产品有太多bug,太多设计问题,某种程度上已经没法修复,必须全部重写。到这种地步需要很长的时间,通常来说会在发布了几个版本之后。但在大部分软件项目的生命周期中有这么个点,在这个点上会有某个人要求一个大变动。首先,这个要求会被推翻,因为每个人都知道重写很麻烦,而且耗费很大。然而,在之后的几个版本发布之后,事实浮出水面,团队才意识到重写已经无法避免。这时候,整个项目不得不停止,强迫重写并不兼容的子系统,然后其他团队也被迫来趋附这些修改。无论最初计划有多现实,最后实现的时间往往都比预期的要长很多。最后,我们终于有了一个全新的产品,没有很多bug,但支持之前一半的功能。这种程序无疑毫无效率可言。

《Practical API Design》一书中写到了避免这种大改动的最佳实践。书中并没有一味关注在未来的进步上,而是先解释了什么是小的、递增、后退的兼容改动,也解释了什么是造成这类改动的原因。这个模式根本不需要会引起混乱的大改动。另一方面,有些时候这类大的改动也会是必须的。这也是为什么本书讨论了提供两种模式并存的方式,也解释了必要时如何在两者之间取得平衡。

如果我们能模块化应用,并把每个模块都当作一个API的类库,就能把重写这样的大改动的需要最小化,相反我们可以不断实现类库的优化。最初投入可能会大些,但长期来看,花销绝对更小。

刚刚所讲的这些都指向这样的答案:“也许软件构架师应该学习更多知识来更恰当地设计API,组建更高效的产品开发团队。”

InfoQ:您对接下来的JDK7的新特性和API,以及被删掉的闭包(Closures)等功能怎么看?

JT:Java首先需要的是每个人都能适应的标准模块系统。最近,我和一个Ruby开发员讨论过Ruby中API设计的优点。首先,看来“duck typing”是Ruby一大长处。其次,我们赞成Ruby的实际优点全在于它的“gems”也就是所有类库的依赖。这方面,Java完全是空白,需要修补。

我知道现在有一些模块系统。顺带一句,NetBeans IDE背后就有一个模块系统。但并不是世界上每个类库的设计都遵循模块化的准则,这必须改变。Java语言本身就应当支持模块化。如果现在Java语言就能实现模块化的话,那我宁愿为闭包(Closures)这些特性再多等几年。

InfoQ:如果要您在Java语言的特性中选出一个最喜欢的,您会选哪个?您最不喜欢的又是哪个呢?

JT:Java据说有很多弱点。但我觉得它其中一个弱点也刚好是它最大的长处:累赘。很对,用其它语言实现同样的功能可能不需要那么多代码。所以,Java确实是累赘。但累赘的好处是程序员可以轻松读懂自己之前写的代码。Java程序对于代码维护员来说也易读易懂。而且,打印出来就可以了,不需要什么IDE的 “go to declaration”功能或者“code completion”特性。我对Java的累赘不是很满意,但我还是很感谢它所带来的可读性。

InfoQ:最后,除了您的书之外,能不能跟大家推荐一本IT、一本非IT方面的书?

JT:我的这本书参阅了《Effective Java》和 Gang of Four的《Design Patterns》。这两本书都是大家耳熟能详的。

除此之外,我还参阅了非常棒的、Petr Vopenka的关于几何历史的一本书—— 《"The Key Stone of European Knowledge"》。刚开始可能会觉得有些闷,但这本书根本不沉闷,而且我非常喜欢。《 Practical API Design》书中的很多“哲学”部分都来源于这本书。如果你觉得我书中那些“哲学”部分很多意思的话,那我建议你也读一下这本书。唯一的问题是,这本书还没有译成英文。

InfoQ:谢谢您,Jaroslav!

查看英文原文Interview and Book Excerpt: Jaroslav Tulach's Practical API Design


感谢曹云飞对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家加入到InfoQ中文站用户讨论组中与我们的编辑和其他读者朋友交流。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

这说法也是可以的…… by Jeffrey Zhao

JT:Java据说有很多弱点。但我觉得它其中一个弱点也刚好是它最大的长处:累赘。很对,用其它语言实现同样的功能可能不需要那么多代码。所以,Java确实是累赘。但累赘的好处是程序员可以轻松读懂自己之前写的代码。Java程序对于代码维护员来说也易读易懂。而且,打印出来就可以了,不需要什么IDE的 “go to declaration”功能或者“code completion”特性。我对Java的累赘不是很满意,但我还是很感谢它所带来的可读性。

《Practical API Design》图灵翻译中 by 刘江 图灵

敬请关注图灵网站:www.turingbook.com

Good book by Bai Hantsy

好书,作者有专门网站维护一个wiki,所有的api设计模式实在都可以从网站上看到。
wiki.apidesign.org

看了采访就有想看书的冲动 by 张 逸

这个采访太厉害,比专门做广告厉害多了。

文中提到的Java模块化,是否是指Ruby中的Module?

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

4 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT