API 设计之禅
API 设计之禅
译者按:本文翻译自 How to design a good API and why it matters。根据笔者经历,很多大厂程序员所写的代码和大厂内部封装的各种中间件、类库,毫不客气地说,90%都是没有经过仔细考虑的,经常有各种各样的性能、拓展、可读性、一致性等问题。本文总结深刻,建议反复阅读学习。文章首发公众号,欢迎关注。
在传统的 API 设计方法中,我尝试将讲座的精华提炼成一系列格言,以帮助开发者更好地理解和设计高质量的 API:
- 所有程序员都是 API 设计师。好的程序是模块化的,模块之间的边界定义了 API。好的模块可以被重用。
- API 可以是你最宝贵的资产,也可能是负担。好的 API 可以创造长期的客户,而差的 API 会造成长期的维护噩梦。
- 公共 API,像钻石一样,永恒存在。你只有一次机会来设计它,所以要尽全力做到最好。
- API 应该易于使用且难以滥用。做简单的事情应该容易,做复杂的事情应该可能,做错误的事情应该尽可能困难或不可能。
- API 应该是自文档化的:对于一个好的 API,代码应该很少需要额外的文档说明。事实上,编写好的 API 代码时,通常也不需要太多文档说明。
- 在设计 API 时,首先要收集需求,且保持一定的怀疑态度。人们通常会提供解决方案,但你的任务是发现潜在的问题并寻找最佳的解决方案。
- 以用例的形式构建需求:用例是你衡量 API 的标准。
- API 的早期草稿应该简短,通常是一页纸,列出类和方法的签名以及一行描述。这能方便你在首次设计不完全正确时进行重构。
- 在实现 API 之前,甚至在它完全规范之前,先编写用例代码。这样可以避免实现或设计出根本不合适的 API。
- 随着 API 的演化,维护用例代码。这不仅能避免突然的意外,而且生成的代码将成为 API 的示例、教程和测试的基础。
- 示例代码应该是典范。如果一个 API 被广泛使用,它的示例将成为成千上万程序的原型。任何错误都会以千倍的速度反弹回来。
- 你无法取悦所有人,所以应该尽量让每个人都不满。大多数 API 都会受到过多的约束。
- 预期由于想象力的局限导致的 API 设计错误。你不可能合理地想象出每个人会如何使用一个 API,或者它将如何与系统的其他部分交互。
- API 设计不是孤立的活动。把你的设计展示给尽可能多的人,并认真听取他们的反馈。那些你没能想到的可能对别人来说是显而易见的。
- 避免固定输入大小的限制。它们会限制 API 的实用性,并加速它的过时。
- 如果难以找到合适的名称,就重新开始设计。不要害怕拆分或合并 API,或将其嵌入更通用的设置中。如果名称开始变得合适,你就走在了正确的轨道上。
- 命名非常重要。追求可读性、一致性和对称性。每个 API 都是一个小语言,人们必须学习如何阅读和书写它。如果你设计得当,代码会像散文一样流畅。
- 当不确定时,去除不必要的部分。如果有 API 设计的基本定理,那就是这一条。这适用于功能、类、方法和参数。API 的每个方面都应该尽可能简洁,但不能少于必要的部分。你可以随时添加,但不能删除。
- 最小化概念上的重量比类或方法的数量更重要。
- 保持 API 远离实现细节。它们会让用户困惑,并且限制了演化的灵活性。什么是实现细节并不总是显而易见的:小心过度规范。
- 最小化可变性。不可变对象简单、线程安全并且可以自由共享。
- 文档很重要。无论 API 多么优秀,没有良好的文档,它都不会被广泛使用。文档应该覆盖每个导出的 API 元素:每个类、方法、字段和参数。
- 考虑 API 设计决策的性能后果,但不要为了性能而扭曲 API。幸运的是,好的 API 通常也能够带来高效的实现。
- API 必须与平台和谐共处,所以要遵循常规。几乎总是错误的做法是将一个平台的 API 直接“翻译”到另一个平台。
- 最小化访问权限;不确定时将其设为私有。这简化了 API,并减少了耦合。
- 只有当你能断言子类的每个实例都是真正的父类实例时,才应该使用子类化。暴露的类不应仅仅为了重用实现代码而子类化。
- 设计并文档化继承,或者禁止继承。这个文档形式是自用模式:类中的方法如何互相使用。如果没有这种文档,安全的子类化是不可能的。
- 不要让客户端做任何库本可以做的事。违反这一规则会导致客户端中大量重复的代码,增加了出错的机会和难度。
- 遵循最小惊讶原则。每个方法应该做出它最不让人惊讶的事情,给定它的名称。如果一个方法没有做用户期望的事情,就会引发 bug。
- 快速失败。报告错误的时机越早,造成的损害越小。编译时失败是最佳的。如果必须在运行时失败,尽量早做失败处理。
- 为所有字符串形式的数据提供编程访问。否则,程序员就不得不手动解析字符串,这很痛苦。而且,字符串形式最终会变成事实上的 API。
- 谨慎使用方法重载。如果两个方法的行为有差异,最好给它们不同的名称。
- 为任务选择合适的数据类型。例如,不要使用字符串,如果有更合适的类型。
- 在方法中保持一致的参数顺序。否则,程序员可能会搞错顺序。
- 避免长参数列表,尤其是那些有多个连续相同类型参数的列表。
- 避免返回值要求特殊处理。客户端会忘记编写特殊处理代码,导致 bug。例如,返回零长度的数组或集合,而不是 null。
- 只有在出现异常情况时才抛出异常。否则,客户端会强迫用异常来处理正常的流程,导致程序难以阅读、易出错或性能较差。
- 抛出未检查的异常,除非客户端能合理地从失败中恢复。
- API 设计是一门艺术,而不是科学。追求美感,并相信你的直觉。不要死板地遵循上述启示,但偶尔合理地违反它们。
通过这些设计原则,你将能够更好地理解和设计高质量、易用、可维护的 API,为长远的开发打下坚实的基础。
本文由博客一文多发平台 OpenWrite 发布!
API 设计之禅的更多相关文章
- javascript的api设计原则
前言 本篇博文来自一次公司内部的前端分享,从多个方面讨论了在设计接口时遵循的原则,总共包含了七个大块.系卤煮自己总结的一些经验和教训.本篇博文同时也参考了其他一些文章,相关地址会在后面贴出来.很难做到 ...
- (转载) RESTful API 设计指南
作者: 阮一峰 日期: 2014年5月22日 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机.平板.桌面电脑.其他专用设备......). 因此,必须有一种统一的机制 ...
- RESTful API 设计指南
转自:http://www.ruanyifeng.com/blog/2014/05/restful_api.html 网络应用程序,分为前端和后端两个部分.当前的发展趋势,就是前端设备层出不穷(手机. ...
- GOTO Berlin: Web API设计原则
在邮件列表和讨论区中有很多与REST和Web API相关的讨论,下面仅是我个人对这些问题的一些见解,并没有绝对的真理,InnoQ的首席顾问Oliver Wolf在GOTO Berlin大会上开始自己的 ...
- RESTful API 设计最佳实践
背景 目前互联网上充斥着大量的关于RESTful API(为了方便,以后API和RESTful API 一个意思)如何设计的文章,然而却没有一个"万能"的设计标准:如何鉴权?API ...
- 我所理解的RESTful Web API [设计篇]
<我所理解的RESTful Web API [Web标准篇]>Web服务已经成为了异质系统之间的互联与集成的主要手段,在过去一段不短的时间里,Web服务几乎清一水地采用SOAP来构建.构建 ...
- 从英文变形规则计算到Restful Api设计
➠更多技术干货请戳:听云博客 一天在研究Restful API设计,命名的时候我总是很纠结,我相信大多数人也有这种感觉,不是说想不出来某个单词怎么写的问题,像我这种没事背单词背到13000词量的人也要 ...
- RESTful API 设计指南 (转)
RESTful API 设计指南 2016-02-23 ImportNew (点击上方公号,可快速关注) 作者:阮一峰 链接:http://www.ruanyifeng.com/blog/2014/0 ...
- 基于资源的权限系统-API设计
概述 权限系统需要和别的系统集成,因此,良好的API是易用性的保证. 这里只设计一些权限相关的核心 API,关于用户,组织,导入导出之类的后续再逐步补充 API 设计 围绕权限有以下 4 类 API: ...
- Atitit. Api 设计 原则 ---归一化
Atitit. Api 设计 原则 ---归一化 1.1. 叫做归一化1 1.2. 归一化的实例:一切对象都可以序列化/toString 通过接口实现1 1.3. 泛文件概念.2 1.4. 游戏行业 ...
随机推荐
- 1000+节点、200+集群,Slack如何利用Karpenter降本增效?
原文首发于云妙算 Slack 是一款 AI 工作管理和协作平台.随着业务需求的增长,Slack 对其内部计算编排平台进行了重大改造,以增强可扩展性.提高效率并降低成本.该内部平台的代号为"B ...
- Spring MVC 3.2 技术预览(一):Servlet 3介绍,异步支持
原文地址:http://blog.springsource.org/2012/05/06/spring-mvc-3-2-preview-introducing-servlet-3-async-supp ...
- JVM的垃圾回收与内存分配
Java是一种内存动态分配和垃圾回收技术的一种语言,不需要显示的进行对象内存的分配,这一切操作都是由JVM来完成的,由于Java是"一切皆对象"的,所以对于内存分配的优化与速度非常 ...
- windows下执行Python脚本
由于业务需要,有些python脚本需要在Windows系统上,并且支持定时执行 1) 一. 创建.bat批处理文件 新创建文件并将扩展名改为.bat 二. 写入执行python脚本的语句 @echo ...
- httpclient 连接池测试
为什么需要使用http连接池 1.降低延迟:如果不采用连接池,每次连接发起Http请求的时候都会重新建立TCP连接(经历3次握手),用完就会关闭连接(4次挥手),如果采用连接池则减少了这部分时间损耗, ...
- web移动端基础
1.像素密度 PPI 说到屏幕就离不开2个因素,屏幕大小和屏幕分辨率. PPI是Pixels Per Inch缩写,pixels per inch所表示的是每英寸所拥有的像素(pixel)数目. PP ...
- 销讯通-CRM系统的功能远远不止于用来打卡
在信息化的过程中,CRM系统其实很多企业都在用,最开始的设想是很好的,大家用着之后发现它可能最终只会沦为一个上班打卡考核或者是最基础的一个签到工具了,没有发挥它应有的一个功能. 最基础的一个诉求 我们 ...
- vue开发一个简单的组件
首先在项目中新建一个js文件 在文件内创建一个对象,对象内创建install方法,将对象用export default暴漏出去 export default{ install(){ console.l ...
- ProcessExplorer 多功能任务管理器软件-中文绿色单文件版
今天我和大家分享一款系统监控工具--ProcessExplorer.一个比Windows自带的任务管理器更强大的工具.感觉最实用的是他的搜索功能,可以搜到系统任务管理器里面无法显示的应用, 大家可以网 ...
- 搭建 zerotier 的行星服务
放弃moon节点,直接搭建Zerotier根服务器_软件应用_什么值得买 Zerotier的优点在于其部署十分简便,只需在zerotier官网注册登陆并创建网络,在自己的设备安装客户端加入网络后,ze ...