如何设计一个良好的API接口

fisherMartyn bio photo By fisherMartyn

起源

这篇文章主要是看了Joshua Bloch的How to Design a Good API and Why it Matters,觉得写的很好,这里是一些提炼和翻译工作

为什么API设计很重要

  • API是公司最重要的财富之一

    • 会有大量的使用
    • 停止使用一个API代价高昂
    • 良好的公共API会留住使用者
  • API也可能成为公司巨大的负担

    • 设计不良的API会导致无尽的客户支持电话呼入
  • 公共API几乎是永久存在的

    • 只有一次机会将其设计良好

为什么API设计对开发者很重要

  • 代码是模块化的

    • 作为API设计者,代码是模块化的,每个模块都有一套API
  • 重要的模块会被复用

    • 一旦有用户使用API,就很难随性的修改;良好的可重用的模块是公司的巨大财富(降低修改成本、维护成本)
  • 以API的角度思考会潜在的提升代码质量

好的API的几个特点

  • 易于学习
  • 即使没有文档说明,也很容易使用
  • 很难用错
  • 使用API不会让业务方的代码难以阅读和维护
  • 足够满足需求
  • 容易扩展
  • 适合观众(Appropriate to audience,不知道咋翻译)

API设计的推荐过程

  • 带着合理的怀疑收集需求

    1)不要直接接受业务方推荐的方案,可能有更好的!

    2)根据使用场景提取出真实的需求。

    3)在这个阶段可以更容易的抽象出更具收益和更通用的东西。

  • 首先设计接口规范(尽量不要超过一页纸)

    1)在这个阶段,欣赏更敏捷的修改,而不是一蹴而就

    2)让尽量多的人阅读spec,看他们的需求是否能满足

    3)保持spec短小,这样更容易修改

    4)直到你非常自信(不会再有修改),再去实现它。

  • 在API进入下一步之前

    1)没有良好的spec之前不要去实现它,因为你会将第一次实现丢掉。

    2)没有良好的需求收集之前不要写spec,因为你会扔掉spec。

    3)遵循上述规则会让你避免恶心的、出人意料的状况发生。

    4)很经典的一句话,代码依靠使用示例和单元测试而继续存在(Code lives on as examples, unit tests)。

  • 提供SPI需要更谨慎

    1)SPI,也就是服务提供接口(Service Provider IInterface),例如JAVA的JCE,插件式的接口要支持多种实现。

    2)实现多个插件测试后再提供接口。

    3)三个原理(The Rule of Threes),如果只实现了一个,可能不能够支持另一个;如果实现了两个,支持其他的可能会有难度;如果实现了三个,会工作的很好。

  • 正视理想和现实

    1)大多数的API设计是过度限制的。不可能满足所有人的需求。

    2)开放的态度针对API的错误。几年的实际情况的使用会洗出所有的错误,开放的态度应对API发展。

通用的原则

  • API应该只做好一件事情

    1)功能要易于解释,如果很难命名,这不是个好信号

    2)好的命名驱动开发

    3)模块要经得起拆分和合并

  • API尽量做到最小

    1)API应该满足其需求。

    2)如果不确定,就先不要加进去,因为对于API,加法容易减法难

  • 实现不应该影响API

    1)实现的细节不应该暴露。

    2)要清楚什么是实现细节。过度固定方法的行为,例如hash就是实现细节。

  • 最小可见性原则

    1)尽量使用private,而不是public的方法或者属性。

    2)public类不应该有public 属性。

    3)最大程度的信息隐藏。

    4)允许模块独立使用、理解、编译、测试和调试

  • 命名很重要

    1)API就是一门很小型的语言

    2)保持一致性,在所有环境中使用相同的单词描述同一事物

    3)力求规律,力求一致

    4)代码如诗

  • 文档很重要

    1)好的设计和好的文档同样重要,缺一不可。

  • 把性能当成是API设计的结果

    1)不要为了性能而扭曲API设计,性能易于优化,API设计的痛苦很难修复

    2)好的设计和好的性能分不开

  • API要保持和平台特性的一致

    1)遵循规范。包括命名规范、避免淘汰的参数和返回值类型。

    2)利用API友好的特性。例如范型、枚举、默认参数

TODO

继续翻译和完善,增加关于类、方法设计的内容。