你如何定义好的或坏的API?

fms*_*msf 61 api api-design

背景:

我正在我的大学上课,名为"软件约束".在第一次讲座中,我们学习了如何构建优秀的API.

我们得到一个非常糟糕的API函数的一个很好的例子是public static void Select(IList checkRead, IList checkWrite, IList checkError, int microseconds);C#中的套接字.该函数接收3个套接字列表,并销毁它们,使得用户必须克隆所有套接字才能将它们送入Select().它还有一个超时(以微秒为单位),它是一个int,用于设置服务器等待套接字的最长时间.这个限制是+/- 35分钟(因为它是一个int).


问题:

  1. 你如何将API定义为"坏"?
  2. 你如何将API定义为"好"?

需要考虑的要点:

  • 难以记住的函数名称.
  • 功能参数很难理解.
  • 文档不好.
  • 一切都是如此相互关联,如果你需要更改1行代码,你实际上需要在其他地方更改数百行.
  • 破坏其论点的函数.
  • 由于"隐藏"的复杂性导致可扩展性差.
  • 用户/ dev需要围绕API构建包装器以便可以使用它.

Tim*_*Tim 106

在API设计中,我总是发现这个主题演讲非常有用:
如何设计一个好的API及其重要性 - 作者:Joshua Bloch

这是一段摘录,我建议阅读整篇文章/观看视频.

II.一般原则

  • API应该做一件事并做得好
  • API应尽可能小但不小
  • 实施不应影响API
  • 尽量减少一切的可访问性
  • 名称Matter-API是一种小语言
  • 文件事项
  • 宗教文件
  • 考虑API设计决策的性能后果
  • API设计决策对性能的影响是真实和永久的
  • API必须与平台和平共存

III.班级设计

  • 尽量减少可变性
  • 子类只在它有意义的地方
  • 继承或其他的设计和文件禁止它

IV.方法设计

  • 不要让客户做模块可以做的任何事情
  • 不要违反最小惊讶原则
  • 快速失败 - 发生错误后尽快报告错误
  • 以字符串形式提供对所有可用数据的编程访问
  • 小心超载
  • 使用适当的参数和返回类型
  • 跨方法使用一致的参数排序
  • 避免长参数列表
  • 避免要求异常处理的返回值

  • 当我看到"文件宗教"时,我不禁想起使用安提阿神圣手榴弹的指示. (3认同)
  • +1这比我的回答更加完整和有用.值得阅读. (2认同)
  • "并且Saint Stallman提高了API,说,"主啊,祝福这个你的API,用它可以与你的操作系统接口......" (2认同)

Qui*_*ome 43

您无需阅读文档即可正确使用它.

一个很棒的API的标志.

  • 极简主义API - 意味着没有混淆调用哪些方法.良好的命名使您可以轻松找到您正在寻找的方法.如果您使用API​​不正确等原因可以纠正您的错误. (3认同)
  • 我还看到了一些优秀的API,它们基本上是自我记录的,通过非常好的设计,正确的命名和简洁的注释/描述.简单的头文件如何突然变成您所需要的,这简直令人着迷. (3认同)
  • 究竟。使用SQLite ADO Wrapper 2.0是一个示例,在该示例中,通过查看类,方法或异常的名称,您实际上可以(正确)猜测会发生什么。 (2认同)

Bar*_*lly 14

许多编码标准和更长的文档甚至书籍(框架设计指南)都是针对这一主题编写的,但其中大部分内容仅在相当低的水平上有所帮助.

还有品味问题.API可以遵守任何规则手册中的每一条规则,并且由于对各种时尚意识形态的盲目遵守而仍然很糟糕.最近的一个罪魁祸首是模式导向,其中Singleton模式(仅比初始化的全局变量更多)和Factory Patterns(一种参数化构造的方式,但通常在不需要时实现)被过度使用.最近,控制反转(IoC)和微小接口类型数量的相关爆炸更可能为设计增加了冗余的概念复杂性.

最好的品味导师是模仿(阅读大量的代码和API,找出有效和无效的东西),体验(犯错误和从中学习)和思考(不要只是为了它自己而做的时尚,三思而后行).


Tim*_*Tim 12

  • 有用 - 它解决了尚未满足的需求(或改进现有需求)
  • 易于解释 - 对它的作用的基本理解应该很容易掌握
  • 遵循一些问题领域或现实世界的一些对象模型.它使用有意义的结构
  • 正确使用同步和异步调用.(不要阻止需要时间的事情)
  • 良好的默认行为 - 在可能的情况下允许可扩展性和调整,但为简单情况提供所有必需的默认值
  • 样品使用和工作样品应用.这可能是最重要的.
  • 优秀的文档
  • 吃自己的狗粮(如果适用)
  • 保持小或分段,使其不是一个巨大的污染空间.保持功能集独立和隔离,几乎没有任何依赖.

还有更多,但这是一个良好的开端


Dan*_*ton 7

一个好的API有一个接近它描述的东西的语义模型.

例如,用于创建和操作Excel电子表格的API将有类,如Workbook,SheetCell,与类似的方法Cell.SetValue(text)Workbook.listSheets().


T.E*_*.D. 7

一个好的API允许客户端做他们需要做的几乎所有事情,但不要求他们做很多盲目忙碌的工作."无意识忙碌工作"的例子是初始化数据结构字段,按顺序调用几个例程,这些例程永远不会因中间没有真正的自定义代码而变化,等等.

如果您的客户都希望用自己的帮助程序代码包装它,那么最糟糕的API就是最糟糕的迹象.至少,您的API应该提供了帮助程序代码.最有可能的是,它应该被设计为提供客户每次自己滚动的更高级别的抽象.


jas*_*nco 6

我一直很喜欢名为API Design Matters的队列中的这篇文章

http://queue.acm.org/detail.cfm?id=1255422

此列还涉及API设计问题:

http://queue.acm.org/detail.cfm?id=1229903