API 设计之禅

news/2025/1/22 23:07:33/文章来源:https://www.cnblogs.com/HuaTalkHub/p/18686927

API 设计之禅

译者按:本文翻译自 How to design a good API and why it matters。根据笔者经历,很多大厂程序员所写的代码和大厂内部封装的各种中间件、类库,毫不客气地说,90%都是没有经过仔细考虑的,经常有各种各样的性能、拓展、可读性、一致性等问题。本文总结深刻,建议反复阅读学习。文章首发公众号,欢迎关注。

在传统的 API 设计方法中,我尝试将讲座的精华提炼成一系列格言,以帮助开发者更好地理解和设计高质量的 API:

  1. 所有程序员都是 API 设计师。好的程序是模块化的,模块之间的边界定义了 API。好的模块可以被重用。
  2. API 可以是你最宝贵的资产,也可能是负担。好的 API 可以创造长期的客户,而差的 API 会造成长期的维护噩梦。
  3. 公共 API,像钻石一样,永恒存在。你只有一次机会来设计它,所以要尽全力做到最好。
  4. API 应该易于使用且难以滥用。做简单的事情应该容易,做复杂的事情应该可能,做错误的事情应该尽可能困难或不可能。
  5. API 应该是自文档化的:对于一个好的 API,代码应该很少需要额外的文档说明。事实上,编写好的 API 代码时,通常也不需要太多文档说明。
  6. 在设计 API 时,首先要收集需求,且保持一定的怀疑态度。人们通常会提供解决方案,但你的任务是发现潜在的问题并寻找最佳的解决方案。
  7. 以用例的形式构建需求:用例是你衡量 API 的标准。
  8. API 的早期草稿应该简短,通常是一页纸,列出类和方法的签名以及一行描述。这能方便你在首次设计不完全正确时进行重构。
  9. 在实现 API 之前,甚至在它完全规范之前,先编写用例代码。这样可以避免实现或设计出根本不合适的 API。
  10. 随着 API 的演化,维护用例代码。这不仅能避免突然的意外,而且生成的代码将成为 API 的示例、教程和测试的基础。
  11. 示例代码应该是典范。如果一个 API 被广泛使用,它的示例将成为成千上万程序的原型。任何错误都会以千倍的速度反弹回来。
  12. 你无法取悦所有人,所以应该尽量让每个人都不满。大多数 API 都会受到过多的约束。
  13. 预期由于想象力的局限导致的 API 设计错误。你不可能合理地想象出每个人会如何使用一个 API,或者它将如何与系统的其他部分交互。
  14. API 设计不是孤立的活动。把你的设计展示给尽可能多的人,并认真听取他们的反馈。那些你没能想到的可能对别人来说是显而易见的。
  15. 避免固定输入大小的限制。它们会限制 API 的实用性,并加速它的过时。
  16. 如果难以找到合适的名称,就重新开始设计。不要害怕拆分或合并 API,或将其嵌入更通用的设置中。如果名称开始变得合适,你就走在了正确的轨道上。
  17. 命名非常重要。追求可读性、一致性和对称性。每个 API 都是一个小语言,人们必须学习如何阅读和书写它。如果你设计得当,代码会像散文一样流畅。
  18. 当不确定时,去除不必要的部分。如果有 API 设计的基本定理,那就是这一条。这适用于功能、类、方法和参数。API 的每个方面都应该尽可能简洁,但不能少于必要的部分。你可以随时添加,但不能删除。
  19. 最小化概念上的重量比类或方法的数量更重要
  20. 保持 API 远离实现细节。它们会让用户困惑,并且限制了演化的灵活性。什么是实现细节并不总是显而易见的:小心过度规范。
  21. 最小化可变性。不可变对象简单、线程安全并且可以自由共享。
  22. 文档很重要。无论 API 多么优秀,没有良好的文档,它都不会被广泛使用。文档应该覆盖每个导出的 API 元素:每个类、方法、字段和参数。
  23. 考虑 API 设计决策的性能后果,但不要为了性能而扭曲 API。幸运的是,好的 API 通常也能够带来高效的实现。
  24. API 必须与平台和谐共处,所以要遵循常规。几乎总是错误的做法是将一个平台的 API 直接“翻译”到另一个平台。
  25. 最小化访问权限;不确定时将其设为私有。这简化了 API,并减少了耦合。
  26. 只有当你能断言子类的每个实例都是真正的父类实例时,才应该使用子类化。暴露的类不应仅仅为了重用实现代码而子类化。
  27. 设计并文档化继承,或者禁止继承。这个文档形式是自用模式:类中的方法如何互相使用。如果没有这种文档,安全的子类化是不可能的。
  28. 不要让客户端做任何库本可以做的事。违反这一规则会导致客户端中大量重复的代码,增加了出错的机会和难度。
  29. 遵循最小惊讶原则。每个方法应该做出它最不让人惊讶的事情,给定它的名称。如果一个方法没有做用户期望的事情,就会引发 bug。
  30. 快速失败。报告错误的时机越早,造成的损害越小。编译时失败是最佳的。如果必须在运行时失败,尽量早做失败处理。
  31. 为所有字符串形式的数据提供编程访问。否则,程序员就不得不手动解析字符串,这很痛苦。而且,字符串形式最终会变成事实上的 API。
  32. 谨慎使用方法重载。如果两个方法的行为有差异,最好给它们不同的名称。
  33. 为任务选择合适的数据类型。例如,不要使用字符串,如果有更合适的类型。
  34. 在方法中保持一致的参数顺序。否则,程序员可能会搞错顺序。
  35. 避免长参数列表,尤其是那些有多个连续相同类型参数的列表
  36. 避免返回值要求特殊处理。客户端会忘记编写特殊处理代码,导致 bug。例如,返回零长度的数组或集合,而不是 null。
  37. 只有在出现异常情况时才抛出异常。否则,客户端会强迫用异常来处理正常的流程,导致程序难以阅读、易出错或性能较差。
  38. 抛出未检查的异常,除非客户端能合理地从失败中恢复
  39. API 设计是一门艺术,而不是科学。追求美感,并相信你的直觉。不要死板地遵循上述启示,但偶尔合理地违反它们。

通过这些设计原则,你将能够更好地理解和设计高质量、易用、可维护的 API,为长远的开发打下坚实的基础。

本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/873470.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3 —— 安装及配置环境

Vue3的安装、配置(✿◕‿◕✿)Vue官网:https://vuejs.org/配置环境终端:Linux和Mac上可以用自带的终端。Windows上推荐用powershell或者cmd。Git Bash有些指令不兼容。安装Node.js:安装地址:https://nodejs.org/en/安装@vue/cli:执行:npm i -g @vue/cli如果执行后面的操作…

二. Redis 超详细的安装教程((七步)一步一步指导,步步附有截屏操作步骤)

二. Redis 超详细的安装教程((七步)一步一步指导,步步附有截屏操作步骤) @目录二. Redis 超详细的安装教程((七步)一步一步指导,步步附有截屏操作步骤)1. Redis 详细安装教程2. Redis 后台基本启动 & 详细的基本使用3. Redis 服务器的关闭和启动的注意事项4. 如何修改 Re…

数据分库分表和迁移方案

在我们业务快速发展的过程中,数据量必然也会迎来突飞猛涨。那么当我们的数据量百倍、千倍、万倍、亿倍增长后,原有的单表性能就不能满足我们日常的查询和写入了,此时数据架构就不得不进行拆分,比如单表拆分成10张表、100张表、单个月分多张表等等。下面我们针对具体案例分析…

Power BI 连接GaussDB提取数据方法

Power BI本身没有直接的链接器来获取GaussDB,目前连接GaussDB的方法有2个: ODBC, JDBC,这两种方式在云端都要通过设置网关,pbi云端通过网关链接到虚拟机或者某台电脑上,电脑安装个人网关(组织网关没有成功,不知道为什么,知道原因的希望能留言),下面说下两种连接方式: …

2025-1-20-盒子模型-弹性盒子模型

重新学一下巩固,之前发的看不了,本来还想着直接看呢 盒子模型 width,height是宽高,padding是内边距,如果里边有文本的话一般是贴着左上方,但是有内边距就不会,类似下边的演示图;border是内外之间边框,就是给宽高之外加一层;margin是外边距,可以理解为是你构造的边框…

【Ubuntu】安装OpenSSH启用远程连接

【Ubuntu】安装OpenSSH启用远程连接 零、安装软件 使用如下代码安装OpenSSH服务端: sudo apt install openssh-server壹、启动服务 使用如下代码启动OpenSSH服务端: sudo systemctl start ssh贰、配置SSH(可跳过) 配置文件 OpenSSH的配置文件所在位置:/etc/ssh/sshd_confi…

CTF-web第二步!

菜狗杯web的传说之下。打开F12,发现有个Game=new Underophidian(gameCanvas)表明有个Game变量存储着数据。在控制台输入Game获取,根据题意,修改分数,然后玩一下就可以得到flag了。

【CodeForces训练记录】Codeforces Round 1000 (Div. 2)

训练情况赛后反思 C题猜了个假结论WA4,每次选择度最多的删掉,在连续三个度都是最大的情况下,删中间的会寄 A题 有点前缀和的感觉,\([1,l]\) 互质个数为 \(l\),\([1,r]\) 互质个数为 \(r\),所以区间 \([l,r]\) 的个数就是 \(r-l\),特判一下 \(l=1,r=1\) 的情况答案是 \(1\…

GUIClip在IMGUI中的作用

目录简介IMGUIGUIClipPush Pop Count局部坐标StyleDraw中Rect点的位置鼠标位置绝对坐标ScrollOffset对局部坐标的影响局部坐标和绝对坐标的相互转化裁剪参考链接 简介 Unity中的IMGUI是一个独立于ugui的UI系统。IMGUI是事件(消息)驱动的UI系统,主要用于编写开发工具。 Unity官…

ceph-安装

【os】 ubuntu1804 【文心上找到的】 【步骤】一、环境准备‌配置节点名称‌:配置集群各节点的hostname,确保互相可以通过hostname来解析节点IP,不需要通过DNS。 ‌时间同步‌:确保所有节点的时间同步,以避免时间不一致导致的问题。 ‌关闭防火墙和SELinux‌:为了简化安装…

开源项目芋道源码解析 [开篇]

文章首发于我的博客:https://blog.liuzijian.com/post/source-code-about-ruoyi-vue-pro.html 1.引言 芋道(又名yudao,ruoyi-vue-pro)是一个基于spring-boot框架的单体Java后端开源项目,拥有基于RBAC模型的组织架构管理、CRM、ERP、商城、代码生成、AI等多个功能模块。封装了…

【跟着阿舜学音乐-笔记】2.2了解架子鼓

2.2了解架子鼓 架子鼓:学名爵士鼓,最早起源于爵士乐,后演变为流行音乐中最主要的套鼓。这里展示一下架子鼓构成2.2.1.底鼓 低音大鼓,在整套乐器中声音最低、最重的鼓,它主要的作用就是铺设节奏。导入导出音轨时,一般写作BD,即英文Bass Drum。(在音乐当中,越是低音的部…