写点什么

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

  • 2009-11-16
  • 本文字数:4451 字

    阅读完需:约 15 分钟

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 中文站用户讨论组中与我们的编辑和其他读者朋友交流。

2009-11-16 01:322895
用户头像

发布了 71 篇内容, 共 22.9 次阅读, 收获喜欢 3 次。

关注

评论

发布
暂无评论
发现更多内容

AI 网关代理 LLMs 最佳实践

阿里巴巴云原生

阿里云 云原生 云原生AI网关

BOE(京东方)打造东北首个沉浸式数字艺术体验空间 科技解码文明释放数字文旅想象力

爱极客侠

小猫在流浪:城市灯火下的无声挽歌

花十君

产品 流浪猫 关爱流浪动物

首批!天翼云息壤智算一体机顺利通过信通院三项测试!

天翼云开发者社区

人工智能 云计算 智算一体机

数智先锋 | 博睿数据赋能蒙牛集团构建大型企业的应用高级可观测能力

博睿数据

1688商品详情API接口(1688.item_get)

tbapi

1688API 1688数据采集 1688商品详情API

模型即产品?从应用角度看AI产品发展趋势

秃头小帅oi

BeeWorks内网im即时通讯,安全的企业内部沟通工具

BeeWorks

IM 即时通讯IM 私有化部署 局域网视频软件

CAD动态块编辑设置参数显示颜色方法

极客天地

SD-WAN能为医疗信息化升级提供哪些帮助?

Ogcloud

SD-WAN SD-WAN组网 SD-WAN厂商 sd-wan专线 SD-WAN厂家

通义灵码与魔搭 Notebook 深度集成:在线编码开箱即用,开发效率倍增

阿里巴巴云原生

阿里云 云原生

DialogHub上线OpenHarmony开源社区,高效开发鸿蒙应用弹窗

HarmonyOS开发者

智能制造:ERP的发展介绍与理解感悟

积木链小链

数字化转型 制造业 智能制造

25年河南等级保护测评公司名单看这里!

行云管家

网络安全 等保 等保测评

量子计算与人工智能的结合:未来科技的双重革命

天津汇柏科技有限公司

人工智能 量子计算

10倍降本、10倍无损弹性!Kafka Serverless 基础版与专业版重磅发布!

阿里巴巴云原生

kafka 阿里云 云原生

故障定位系列-1-Web应用接口级故障如何定位

乘云数字DataBuff

运维 故障定位 智能运维 运维监控

【解决方案】多租户技术架构设计入门(一)

量贩潮汐·WholesaleTide

架构 多租户

抖音商品详情 API 接口(dy.item_get)全解析

tbapi

抖音API 抖音商品详情API

【FAQ】HarmonyOS SDK 闭源开放能力 —Account Kit(3)

HarmonyOS SDK

harmoyos

通义灵码与魔搭 Notebook 深度集成:在线编码开箱即用,开发效率倍增

阿里云云效

阿里云 云原生 通义灵码

堡垒机软件有哪些?举例一个说说!

行云管家

网络安全 堡垒机 云堡垒机

全彩LED大屏幕亮度过高的影响以及如何调整?

Dylan

行业 LED显示屏 全彩LED显示屏 户外LED显示屏 led显示屏厂家

Apache Doris 2.1.9 版本正式发布

SelectDB

数据库 大数据 数据仓库 倒排索引 湖仓一体

CAD编辑图块属性对话框不见了

极客天地

AI时代的数据底座:火山引擎多模态数据湖的设计与实践

极客天地

函数计算支持热门 MCP Server 一键部署

阿里巴巴云原生

阿里云 Serverless 云原生 函数计算

TUSD运营商亏空近5亿美元,FDUSD发行方是罪魁祸首?

TechubNews

去中心化 孙宇晨 FDUSD

蚂蚁清华联合发布 AReaL-boba,代码数据全开源,助力社区轻松复现 SOTA 推理模型

蚂蚁开源

开源 强化学习 蚂蚁

Excel百万数据如何快速导入?

不在线第一只蜗牛

Excel

淘宝商品详情API+拍立淘实战:如何用技术重新定义"找货"?

代码忍者

淘宝API接口

采访和书摘:Jaroslav Tulach的Practical API Design_Java_Srini Penchikala_InfoQ精选文章