如何定义 API 的好坏?

发布于 2024-07-12 10:51:55 字数 700 浏览 8 评论 0原文

背景:

我正在大学上一门名为“软件约束”的课程。 在第一堂课中,我们学习了如何构建良好的 API。

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


问题:

  1. 如何将 API 定义为 '坏的'?
  2. 你如何定义一个 API“好”吗?

需要考虑的要点:

  • 难以记住的函数名称。
  • 难以理解的函数参数。
  • 糟糕的文档。
  • 一切都如此相互关联,如果您需要更改 1 行代码,您实际上需要更改其他地方的数百行代码。
  • 破坏其参数的函数。
  • 由于“隐藏”的复杂性导致可扩展性较差。
  • 用户/开发人员需要围绕 API 构建包装器,以便可以使用它。

Background:

I am taking a class at my university called "Software Constraints". In the first lectures we were learning how to build good APIs.

A good example we got of a really bad API function is the socket public static void Select(IList checkRead, IList checkWrite, IList checkError, int microseconds); in C#. The function receives 3 lists of sockets, and destroys them making the user have to clone all the sockets before feeding them into the Select(). It also has a timeout (in microseconds) which is an int, that sets the maximum time the server can wait for a socket. The limits of this is +/-35 minutes (because it is an int).


Questions:

  1. How do you define an API as
    'bad'?
  2. How do you define an
    API as 'good'?

Points to consider:

  • Function names that are hard to remember.
  • Function parameters that are hard to understand.
  • Bad documentation.
  • Everything being so interconnected that if you need to change 1 line of code you will actually need to change hundreds of lines in other places.
  • Functions that destroy their arguments.
  • Bad scalability due to "hidden" complexity.
  • It's required from the user/dev to build wrappers around the API so that it can be used.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

凉栀 2024-07-19 10:51:56

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

这是摘录,我建议阅读全文/观看视频。

二. 一般原则

  • API 应该只做一件事,而且要把它做好
  • API 应尽可能小,但不能更小
  • 实施不应影响 API
  • 尽量减少所有内容的可访问性
  • 名称很重要 - API 是一门小语言
  • 文档很重要
  • 宗教性地记录
  • 考虑 API 设计决策的性能影响
  • API 设计决策对性能的影响是真实且永久的
  • API 必须与平台和平共存

三. 类设计

  • 最小化可变性
  • 仅在有意义的地方进行子类化
  • 为了继承而设计和记录,否则禁止

四。 方法设计

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

In API design I've always found this keynote very helpful:
How to Design a Good API and Why it Matters - by Joshua Bloch

Here's an excerpt, I'd recommend reading the whole thing / watching the video.

II. General Principles

  • API Should Do One Thing and Do it Well
  • API Should Be As Small As Possible But No Smaller
  • Implementation Should Not Impact API
  • Minimize Accessibility of Everything
  • Names Matter–API is a Little Language
  • Documentation Matters
  • Document Religiously
  • Consider Performance Consequences of API Design Decisions
  • Effects of API Design Decisions on Performance are Real and Permanent
  • API Must Coexist Peacefully with Platform

III. Class Design

  • Minimize Mutability
  • Subclass Only Where it Makes Sense
  • Design and Document for Inheritance or Else Prohibit it

IV. Method Design

  • Don't Make the Client Do Anything the Module Could Do
  • Don't Violate the Principle of Least Astonishment
  • Fail Fast - Report Errors as Soon as Possible After They Occur
  • Provide Programmatic Access to All Data Available in String Form
  • Overload With Care
  • Use Appropriate Parameter and Return Types
  • Use Consistent Parameter Ordering Across Methods
  • Avoid Long Parameter Lists
  • Avoid Return Values that Demand Exceptional Processing
玻璃人 2024-07-19 10:51:56

您不必阅读文档即可正确使用它。

这是一个很棒的 AP​​I 的标志。

You don't have to read the documentation to use it correctly.

The sign of an awesome API.

花心好男孩 2024-07-19 10:51:56

许多编码标准和更长的文档,甚至书籍(框架设计指南) 已就此主题撰写,但其中大部分仅在相当低的水平上有所帮助。

还有一个品味问题。 API 可能会遵守任何规则手册中的每条规则,但由于对各种流行意识形态的盲目坚持,仍然很糟糕。 最近的罪魁祸首是面向模式,其中单例模式(只不过是初始化的全局变量)和工厂模式(一种参数化构造的方法,但通常在不需要时实现)被过度使用。 最近,控制反转 (IoC) 和相关的微小接口类型数量激增更有可能增加了设计的冗余概念复杂性。

品味最好的导师是模仿(阅读大量代码和 API,找出哪些有效,哪些无效)、经验(犯错误并从中学习)和思考(不要只为了流行而做,三思而后行)。

Many coding standards and longer documents and even books (Framework Design Guidelines) have been written on this topic, but much of this only helps at a fairly low level.

There is also a matter of taste. APIs may obey every rule in whatever rulebook, and still suck, due to slavish adherence to various in-vogue ideologies. A recent culprit is pattern-orientation, wherein Singleton Patterns (little more than initialized global variables) and Factory Patterns (a way of parameterizing construction, but often implemented when not needed) are overused. Lately, it's more likely that Inversion of Control (IoC) and associated explosion in the number of tiny interface types that adds redundant conceptual complexity to designs.

The best tutors for taste are imitation (reading lots of code and APIs, finding out what works and doesn't work), experience (making mistakes and learning from it) and thinking (don't just do what's fashionable for its own sake, think before you act).

戴着白色围巾的女孩 2024-07-19 10:51:56
  • 有用 - 它解决了尚未满足的需求(或改进了现有需求)
  • 易于解释 - 对它所做的事情的基本理解应该很容易掌握
  • 遵循某些问题域或现实世界的某些对象模型。 它使用有意义的构造
  • 正确使用同步和异步调用。 (不要阻止需要时间的事情)
  • 所需的所有内容提供默认值
  • 良好的默认行为 - 在可能的情况下允许可扩展性和调整,但为简单案例示例使用和工作示例应用程序 。 这可能是最重要的。
  • 优秀的文档
  • 吃你自己的狗粮(如果适用)
  • 保持较小或分段,这样它就不会成为一个巨大的污染空间。 保持功能集的独特和隔离,几乎没有依赖关系。

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

  • Useful - it addresses a need that is not already met (or improves on existing ones)
  • Easy to explain - the basic understanding of what it does should be simple to grasp
  • Follows some object model of some problem domain or real-world. It uses constructs that make sense
  • Correct use of synchronous and asynchronous calls. (don't block for things that take time)
  • Good default behavior - where possible allow extensibility and tweaking, but provide defaults for all that is necessary for simple cases
  • Sample uses and working sample applications. This is probably most important of all.
  • Excellent documentation
  • Eat your own dog food (if applicable)
  • Keep it small or segment it so that it is not one huge polluted space. Keep functionality sets distinct and isolated with few if any dependencies.

There are more, but that is a good start

忆伤 2024-07-19 10:51:56

好的 API 具有与其所描述的事物相近的语义模型。

例如,用于创建和操作 Excel 电子表格的 API 将具有诸如 WorkbookSheet< 之类的类/code> 和 Cell,以及 Cell.SetValue(text)Workbook.listSheets() 等方法。

A good API has a semantic model close to the thing it describes.

For example, an API for creating and manipulating Excel spreadsheets would have classes like Workbook, Sheet, and Cell, with methods like Cell.SetValue(text) and Workbook.listSheets().

预谋 2024-07-19 10:51:56

一个好的 API 允许客户做他们需要做的几乎所有事情,但不需要他们做很多无意识的忙碌工作。 “无意识的忙碌工作”的例子包括初始化数据结构字段、按永远不会变化的顺序调用多个例程,中间没有真正的自定义代码等等。

糟糕的 API 的最明显标志是,如果您的客户都想用他们自己的帮助代码。 至少,您的 API 应该提供该帮助程序代码。 最有可能的是,它的设计应该是为客户每次自行滚动提供更高级别的抽象。

A good API allows the client to do pretty much everything they need to do, but doesn't require them to do a lot of mindless busy-work. Examples of "mindless busy work" would be initializing data structure fields, calling several routines in a sequence that never varies with no real custom code in between, etc.

The surest sign of a bad API is if your clients all want to wrap it with their own helper code. At the absolute least, your API should have provided that helper code. Most likely, it should have been designed to provide the higher level of abstraction the clients are rolling themselves on their own every time.

野稚 2024-07-19 10:51:56

糟糕的 API 是指其目标受众不使用的 API。

好的 API 是由其目标受众用于其设计目的的 API。

优秀的 API 既可以被其预期受众用于其预期目的,也可以被非预期受众出于其设计者未预料到的原因使用。

如果 Amazon 将其 API 同时发布为 SOAP 和 REST,并且 REST 版本胜出,这并不意味着底层 SOAP API 很糟糕。

我想你也是如此。 你可以阅读所有你想要的关于设计的内容,并尽力而为,但严峻的考验将被使用。 花一些时间构建各种方法,以获得有关哪些有效、哪些无效的反馈,并准备好根据需要进行重构以使其变得更好。

A bad API is one that is not used by its intended audience.

A good API is one that is used by its intended audience for the purpose for which it was designed.

A great API is one that is used by both its intended audience, for the its intended purpose, and an unintended audience for reasons unanticipated by its designers.

If Amazon publishes its API as both SOAP and REST, and the REST version wins out, that doesn't mean the underlying SOAP API was bad.

I'd imagine that the same will be true for you. You can read all you want about design and try your best, but the acid test will be use. Spend some time building in ways to get feedback on what works and what doesn't and be prepared to refactor as needed to make it better.

东京女 2024-07-19 10:51:56

我认为一个好的 API 应该允许自定义 IO 和内存管理挂钩(如果适用)。

一个典型的例子是,您拥有磁盘上数据的自定义压缩存档格式,而 API 较差的第三方库想要访问磁盘上的数据,并需要一个可以加载数据的文件路径。

这个链接有一些优点:
http://gamearchitect.net/2008/09/19/good-middleware/< /a>

I think a good API should allow custom IO and memory management hooks if it's applicable.

A typical example is you have your custom compressed archive format for data on disk and a third party library with a poor api wants to access data on disk and expects a path to a file where it can load its data.

This link has some good points:
http://gamearchitect.net/2008/09/19/good-middleware/

一袭水袖舞倾城 2024-07-19 10:51:56

一个好的 API 可以让简单的事情变得简单(用最小的样板文件和学习曲线来完成最常见的事情),也可以让复杂的事情成为可能(最大的灵活性,尽可能少的假设)。 平庸的 API 可以很好地完成其中一项任务(要么非常简单,但前提是您尝试做真正基本的事情,要么非常强大,但学习曲线非常陡峭,等等)。 一个糟糕的 API 就是不能很好地完成这两点。

A good API is one that makes simple things simple (minimum boilerplate and learning curve to do the most common things) and complicated things possible (maximum flexibility, as few assumptions as possible). A mediocre API is one that does one of these well (either insanely simple but only if you're trying to do really basic stuff, or insanely powerful, but with a really steep learning curve, etc). A horrible API is one that does neither of these well.

静待花开 2024-07-19 10:51:56

已经有其他几个很好的答案了,所以我想我只是添加一些我没有看到提到的链接。

文章

  1. “API 设计小手册”,作者:Trolltech 的 Jasmin Blanchette< /a>
  2. “定义 QT 风格的 C++ API”也是 Trolltech

书籍:

  1. < a href="https://rads.stackoverflow.com/amzn/click/com/0321356683" rel="nofollow noreferrer">Joshua Bloch 的“Effective Java”
  2. Kernighan 和 Pike 的“编程实践”

There are several other good answers on this already, so I thought I'd just throw in some links I didn't see mentioned.

Articles

  1. "A Little Manual Of API Design" by Jasmin Blanchette of Trolltech
  2. "Defining QT-Style C++ APIs" also Trolltech

Books:

  1. "Effective Java" by Joshua Bloch
  2. "The Practice Of Programming" by Kernighan and Pike
猫弦 2024-07-19 10:51:56

如果 API 生成错误消息,请确保该消息和诊断可以帮助开发人员找出问题所在。

我的期望是 API 的调用者传入正确的输入。 开发人员是 API(而不是最终用户)生成的任何错误消息的消费者,针对开发人员的消息可以帮助开发人员调试其调用程序。

If the API produces an error message, ensure that the message and diagnostics help a developer work out what the problem is.

My expectation is that the caller of an API passes in input that is correct. A developer is the consumer of any error messages produced by the API (not the end user), and messages aimed at the developer help the developer debug their calling program.

貪欢 2024-07-19 10:51:56

如果 API 记录不完整,那么该 API 就是不好的

如果 API 有良好的文档记录并遵循编码标准,那么它就是好的

现在这是两个非常简单但也很难​​遵循的点,这将其带入软件架构领域。 您需要一位优秀的架构师来构建系统并帮助框架遵循自己的准则。

注释代码、编写解释良好的API 手册是强制性的。

如果 API 有一个很好的文档来解释如何使用它,那么它就是一个好的 API。 但是,如果代码干净、良好并且遵循其内部标准,那么即使它没有像样的文档也没关系。

我写了一些关于编码结构的文章

An API is bad when it is badly documented.

An API is good when it is well documented and follows a coding standard.

Now these are two, very simple and also very hard points to follow, this brings one into the area of software architecture. You need a good architect that structures the system and helps the framework follow its own guidlines.

Commenting code, writing an well explained manual for the API is Mandatory.

An API can be good if it has a good documentation which explains how to use it. But if the code is clean, good and follows a standard inside itself, it doesnt matter if it doenst have a decent documentation.

I've written a little about coding structure here

粉红×色少女 2024-07-19 10:51:56

我认为最重要的是可读性,我的意思是让尽可能多的程序员在最短的时间内理解代码在做什么的质量。 但判断哪个软件可读、哪个不可读,具有难以形容的人类品质:模糊性。 你提到的几点确实在一定程度上成功地使其具体化。 但总的来说,这仍然是一个具体问题具体分析的问题,很难制定出通用的规则。

I think what is paramount is readability, by which I mean the quality that makes the greatest number of programmers to make sense of what the code is doing in the shortest possible amount of time. But judging which piece of software is readable and which is not has that indescribable human quality: fuzziness. The points you mention do partly succeed in crystallizing it. However, in its entirety it has to remain a case-by-case affair and it would be really hard to come up with universal rules.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文