从 Java 大神 Joshua Bloch 提炼 API 设计的三个核心原则

Java设计模式实战:7种核心模式解析与工程应用指南 设计模式是软件工程中解决常见设计问题的经典方案,其核心在于通过封装变化、降低耦合来提升代码的可维护性与扩展性。从原理层面看,设计模式基于面向对象的基本原则,如开闭原则、依赖倒置等,通过定义清晰的接口与抽象来隔离变化点。其技术价值在于为复杂软件系统的架构提供了经过验证的蓝图,能有效应对需求变更与系统演进,避免代码腐化为难以维护的“大泥球”。在应用场景上,无论是管理全局资源的单例模式、封装对象创建的工厂模式,还是实现算法灵活切换的策略模式,都广泛应用于框架设计(如Spring)、中间件及业务系统开发中。本文聚焦 阅读详情

一个 API 应该容易学习和使用,且不易被误用。它还应该随着时间而发展,优秀的设计需要预见并适应这种变化。

file

Joshua Bloch 曾在 Sun 担任杰出工程师,之后加入谷歌成为首席 Java 架构师。他主导了 Java 平台上的很多功能,包括 Java Collections 框架,java.math 包,assert 机制等。他也是 Effective Java 的作者。

在谷歌 2007 年的一场重要演讲中,软件工程师兼技术作家 Joshua Bloch 强调了 API 是一种极其重要的商业资产。他指出,这主要是因为如果 API 对外开放,客户可能会选择在上面进行大量投资,从而很难改变使用习惯。

Bloch 还警告说,设计糟糕的 API 可能会导致无休止的客户支持电话,极大地阻碍公司的发展。

Bloch 进一步指出,以 API 设计为思考核心,能显著提高编写程序的质量。

即使你作为一个程序员并不直接参与面向公众的 API 开发,实际上你也在持续地创建 API。优秀的编程应该是模块化的,模块间的边界自就是 API。同样,如果你参与的是一个现代化的、分布式的、基于微服务架构的系统,那么服务间的边界也构成了 API,只是架构有所不同。

尽管如此,API 设计仍然是许多程序员面临的一个挑战。那么,一个好的 API 有哪些特点呢?

名字至关重要

从宏观角度来看,API 应该易于学习和使用,同时难以被误用。它还需要随着时间的发展而进化,而一个优秀的设计会将此考虑在内。

命名的方式极其重要,因为 API 在实质上是一种需要用户学习的简约语言。

「真正合适的命名可以解决问题并避免误解,因为恰当的命名能够非常明确地表明事物的本质。」SoftIron 首席科学家 Harry Richardson 在接受 The New Stack 采访时表示。

Richardson 特别指出,对于开发者来说,命名塑造了我们的思维模型。

「改变一个已经形成的思维模型是相当困难的工作,这不一定是在代码方面,而是关于我们思考问题方式的方面。」

因此,投入时间去精心挑选一个能够精确描述 API 功能的名称是非常值得的。

作为一个作家的基本工具 —— 字典和词典 —— 在 API 命名过程中也能提供帮助。如果你发现某个名字特别难以确定,这可能意味着它尝试同时承担太多的职责。就像需要将过于复杂的句子分割成更简单的句子一样,当一个模块过于复杂时,也应该考虑将其拆分。

要避免使用让人费解的缩写,并且注意保持命名的一致性。比如,不应该同时使用 getBasicSalary() 和 getBaseSalary() 这样意义相同但命名不一的方法 —— 如果你的 API 中既有 remove() 又有 delete() 方法,使用者能够清楚地知道它们之间的区别吗?

使用的语言需要与组织或供应商公开的其他 API 保持一致性。这种对一致性的追求意味着,实施一定程度的集中化管理会很有帮助。

比如,一些大型企业会把高级技术写作人员的职责扩展到帮助工程团队统一命名方法、属性和字段。

如果你正在开发 REST 风格的系统,独立咨询师兼《掌握 API 架构》一书的合作者 Daniel Bryant 建议参考已有的 API 指南集,这有助于在 API 的行为上实现一致性。对于基于 HTTP 的 API,他推荐考虑使用 OpenAPI,还有其他包括 Atlassian、Google 和 Microsoft 在内的指南。

同时,虽然所有 API 都需要恰当的命名,但这些命名本身是特定于领域的;比如,为量化分析师编写的 API 与为零售商编写的 API 使用的语言会有很大不同。理想情况下,选用的术语应与企业已经使用并至少理解的术语匹配。

为此,Bryant 在对 The New Stack 的讲述中提到,最佳做法是进行用户研究,确保覆盖所有潜在的 API 使用群体。

「QA 团队成员与开发者对于你的 API 应如何运作会有不同的看法,」他说。「我经常见到开发者在没有询问谁会使用它的情况下设计 API,结果暴露了内部的领域模型。」

他推荐从「待完成的工作」(Jobs-to-be-Done)的角度来考虑,比如:你的关键任务是什么?你的工作流是怎样的?你是如何处理它的?你希望如何处理它?最后一个问题至关重要,因为围绕已建立的流程可能会形成惯性。

「如果你能简化复杂事物,你就有可能颠覆人们的世界观,随着系统的演进,通常会出现很好的机会」Bryant说。

最小意外原则

你的 API 也应该符合其所用编程语言的惯常用法,并尊重该语言的工作机制。例如,如果 API 要和 Java 配合使用,就应该通过抛出异常来处理错误,而不是像在 C 语言中那样返回错误代码。

API 应遵循最小意外原则。这一原则部分通过对称性实现;比如说,如果你需要添加和删除方法,这些操作应该在适当的地方被一致地实施。

一个优秀的 API 应该仅包含少数几个概念;在学习它时,不应被迫学习太多内容。这并不特指方法、类或参数的数量,而是指 API 所涵盖的概念范围。理想情况下,一个 API 应该只专注于完成一个任务。

也最好避免无谓地添加任何元素。「不确定时就不要添加,」Bloch 这样建议。你通常可以在需要时向 API 中添加某些内容,但一旦 API 被公开,就无法再移除其中的任何部分。

如之前所述,你的 API 需要随时间发展,因此设计的一个关键方面是,在后续过程中能够进行更改而不破坏整体结构。

「归根到底,关键在于 API 应该反映现实,」Richardson表示。「例如,如果一个人可以有多个地址或电话号码,即便你目前只关注一个,也不应该仅允许存在一个地址。忽略现实最终总会带来问题。」

API 的粘性

Richardson 指出,仅实施你当前需要的 API 的一部分是一个常见的错误模式。这种做法的风险在于,你可能没有彻底思考 API 的设计,最终导致在其他场景下不可用的结果。

「API 设计需要比任何其他事情投入更多的思考,」Richardson 说,「因为一旦建成,你就无法再对其进行更改。」

第二个问题涉及到封装和实现细节的泄露。

「一旦实现细节泄露,你就无法更改它,」Richardson表示。「因此,你需要考虑,这里进行的操作是什么?这个数据结构的真实含义是什么?」

错误处理通常是被忽略的一个领域。比如,如果你使用数据库作为后端存储,就不应该让 SQL 错误直接暴露出来,因为如果你以后想更改存储机制,这样做就会遇到障碍。

就像软件开发的任何其他方面一样,认为你可以孤立地把自己锁在一个房间里独立完成 API 的开发是一个错误。这样做,你可能会过于坚持自己的设计,即便设计存在问题。最好是像对待任何其他系统一样,频繁地与合作方一起测试你的想法。

在开始编码 API 之前,编写一个简短的规格说明书,向合作方展示它将做什么以及如何工作是个不错的主意。规格说明书保持简短,这样可以增加被阅读的可能性,并防止你一开始就过于投入你的方案。如果你花费几个月时间编写了一个 100 页的规格说明书,你就很难承认它可能并不那么优秀。

文档是被极度低估的一方面,这不仅适用于 API 设计,在整个计算机科学领域都是如此。技术文档编写者经常被低估和低薪,而文档最多被当作事后的补充,这种情况常被「代码即文档」这一危险的观点所体现。

虽然你希望你的 API 易于理解和学习,但它的文档仍极为重要。它应当是完整而全面的,至少包含每个方法的用途、每个字段的作用以及可能的错误条件。

「你希望它能列出所有可能返回的错误代码及其对应的情况」

Richardson 强调。

投入时间来打磨和修正文档,避免诸如使用不容易理解的缩写这样的常见错误。

在开发过程中,继续根据 API 编写示例代码。Bloch 提到,许多开发者在开发过程往往半途而废,但是如果在整个实施过程中持续对 API 进行编码,你将能够真实地感受到它的工作时机和方式。

「这些代码不是无用功,」Bloch强调,「因为它不仅帮助你打造出更优秀的产品,还提供了一套可供其他程序员学习的范例。」

这些示例极为关键,因为它们将被其他开发者不断地复制使用,从而根本性地影响 API 的使用方式。


💡 更多资讯,请关注 Bytebase 公号:Bytebase

Java面试核心知识点解析:从基础到JVM优化 Java作为面向对象编程语言的代表,其核心机制包括JVM内存管理、多线程并发控制和集合框架设计。理解值传递与引用传递的本质差异是掌握Java基础的关键,而HashMap的哈希碰撞处理则体现了数据结构优化思想。在并发编程领域,volatile关键字通过内存屏障保证可见性,与synchronized形成互补。JVM的垃圾回收算法从标记-清除到ZGC的演进,反映了对低延迟和高吞吐量的持续追求。这些技术广泛应用于电商系统、金融交易等高性能场景,也是Java开发者面试中的高频考察点。 阅读详情

相关推荐

深耕 Java 代码之道:《Effective Java(第 3 版)》的实践智慧与生态价值

在 Java 技术生态中,有一本著作被誉为 “每个 Java 程序员的案头圣经”—— 它并非讲解基础语法的入门教材,也不是探讨底层原理的深度专著,而是聚焦 “如何写出更好的 Java 代码” 的实践指南。这本由 Java 领域传奇开发者约书亚・布洛克(Joshua Bloch)撰写的《Effective Java(第 3 版)》,自 2018 年出版以来,始终是中高级 Java 工程师进阶的核心读物。它以 3 条原则为纲、90 条最佳实践为目,将作者参与设计 Java 核心类库(如 Collections

数字魔方操控师的博客 526

《Effective Java》:Java编程圣经,Bloch大师亲授高效优雅编程之道!

《Effective Java》:Java编程圣经,Bloch大师亲授高效优雅编程之道!

商务合作欢迎私信我 1万+

Joshua Bloch访谈录.doc

这次Java 2006研讨会请来两位来自Google总部的Java大师Josh Bloch与Neal Gafter 来台湾参加,我和我找来帮我壮胆(从新加坡过来的,英文很好)的同事都获益良多。在联络感情、练英文、以及陪他们在台北吃喝玩乐四天之中,我们聊了不少关?于技术方面的话题。不过我们聊的内容不是在于技术本身怎么去使用,而是聊一些我们对于这些技术的看法,从他们的见解中,有些跟我心中的想法是一致的,只是?现在有大师背书,更加确认我的想法。这算是英雄所见略同吗??

Joshua Bloch离开Google了,Dart前景堪忧

Joshua Bloch,Java界的传奇人物,如果你没有听过他的名字,也肯定看过他的书(Effective Java,Java Concurrency in Practice, Java Puzzlers)。他在哥伦比亚大学和卡内基梅隆大学分别获得计算机本科和博士学位。先是在Sun公司工作,2004年去了Google,是Google的Chief Java Architect。他主持了无数Ja

广告业的程序员 8730

实战:如何通过修改VTS和HTS调整GC4653 sensor帧率(附完整计算步骤)

本文以GC4653图像传感器为例,详细解析了通过修改VTS和HTS寄存器来精确调整输出帧率的完整流程。文章深入剖析了帧率计算公式FPS = PCLK / (VTS × HTS)的核心原理,并提供了从获取寄存器参数、计算目标VTS值到系统验证的实战步骤,帮助工程师掌握独立优化Sensor性能、提升低照度画质的关键技能。

gin88的博客 340

使用LaTex写IEEE trans 论文的参考文献(bib)

(1)在.TeX文件的最下方添加这几行内容,主要为生成tran形式的参考文献,第二行为参考文献名称,我命名为reference.bib,所以写的是reference,要根据自己的命名改写。(5)如果要在文中引用的话,就在.tex文件中添加\cite{},中括号里面内容为方框圈出来部分,但引用之后,在参考文献后面会出现[1]这样的标识,不知道为什么。(4)完成(3)以后,点击工具-命令-LaTeX,编译,然后按照此步骤LaTeX-bibtex-LaTeX-LaTeX,就可以完成参考文献的导入。

qq_45884215的博客 6259

采访Java Collection的作者Joshua Bloch

想必用Java的人都用过JDK的容器类吧,什么List, Set, Map啦。每天这些代码在全世界成千上万的JVM里面运行,每天数以万记的程序员在使用这些类。你知道这些这么cool的代码是谁写的吗?是Joshua Bloch。他以前是在Sun工作,现在跳到Google了,Google是无敌了。他可是大师级别的人物了。虽说他是大师但是人家也在写代码,所以这样的人的文章必定是脚踏实地。而非有些只会动嘴皮子,开会的时候在白板上画出一堆框框线线然后让别人来coding的“专家”。虽然自己写了多年Java也设计了不少

卢声远 Shengyuan Lu的专栏 3858

SNAP计算哨兵二号的叶面积指数(LAI)

对于哨兵二号数据以及LANDSAT8数据,SNAP提供已经集成好的模块计算LAI。在Optical->Thematic Land Processing->Biopyhsical Processor目录下面。 对于经过Sen2Cor处理好的数据,需经过重采样才可进行计算。重采样工具在Raster->Geometric->Resampling。 如果选择Biopyhsical Processor S2_10m进行计算,需要将所有的波段都重采样为10米(哨兵二号的第二波段为10米,可据此波

gxwwww的博客 9418

【JDK学习篇】LinkedList模仿

java中LinkedList的实现,看看Josh Bloch写的源码才发现真正大师的作品,真的是佩服的五体投地 如图就是josh Bloch,自己还买过他的《Efficient java》,不过至今还躺在自己的书架上。 这次看看jdk中的源码从中学习,发现他们写的东西真的注意到很多,不论是安全,还是快捷方面都是自己要学习的。 模仿心得体会 在学习源码时,便对着高淇的java300集...

~yzzheng~的博客 1062

深入解析FPGA中的GTX高速收发器架构与设计原理

本文深入解析了FPGA中GTX高速收发器的核心架构与设计原理。文章将GTX比作数据“高速公路”,详细拆解了其PMA(物理媒介适配层)与PCS(物理编码子层)的双层结构,阐述了串并转换、时钟恢复等关键技术,并提供了时钟源选型(QPLL/CPLL)、上电复位流程及信号完整性调试等实战指南,是掌握高速接口设计的必备知识。

f6g7h8i9j的博客 221

【Unity】【模型】【AI建模】如何将AI生成的GLB格式3D模型文件导入Unity

本文介绍了一个将AI工具自动生成的GLB格式3D模型文件转换成fbx模型文件导入Unity的步骤。

O青草O的博客 Unity和游戏制作知识分享 1360

Joshua Bloch访谈:API对设计流程的影响小结

一:数学与程序 数学归纳法和递归的例子, 但是我认为离散的东西比连续的东西更重要 。二:散文与编程 编程是不同技能的组合。web开发更加注重用户感受,库、编译器以及底层框架也需要代码可读、可维护注重逻辑思维。三:API对设计流程的影响 1.需求分析的重要性怎么强调也不过分。获取用例图。 你就有了用来比较所有备选解决方案优劣的基准。 2.然后编写骨架API。 骨架API应...

自由理想的足迹 249

手把手教你在openclaw中白嫖英伟达羊毛调用GLM5/Minimax2.1/Kimi K 2.5等模型

本文介绍如何在OpenClaw中免费调用英伟达平台的GLM5、Minimax2.1和Kimi K2.5等模型。通过在openclaw.json配置文件中添加NVIDIA的API信息,设置免费模型参数(如contextWindow和maxTokens),并执行简单命令即可切换默认模型。该方法可节省token消耗成本,最后需重启gateway使配置生效。文中还提供了使用其他API平台时的配置模板。

Science prince的博客 5103

如何设计一款优秀的API--Google首席软件工程师Joshua Bloch

优秀API所具备的特征 简单易学;易于使用,即使没有文档;很难误用;易于阅读,代码易于维护;足够强大,可以满足需求;易于扩展;适合用户。 了解了一款优秀API所具备的特征后,一起再来看看如何设计优秀的API,有哪些流程和规则可循,开发者在设计时需要注意哪些事项。 API设计流程中的注意事项 征集需求 在开始之前,你可能会收到一些解决方案,它们不一定会比现有的

gechengling的专栏 875

【Flink】FlinkCDC获取mysql数据时间类型差8小时时区解决方案

​ 1、背景: 在我们使用FlinkCDC采集mysql数据的时候,日期类型是我们很常见的类型,但是FlinkCDC读取出来会和数据库的日期时间不一致,情况如下 FlinkCDC获取的数据中create_time字段1694597238000转换为时间戳2023-09-13 17:27:18,而数据库中原始数据如下,并没有到下午5点,这就导致了FlinkCDC读出来的时间和数据库中实际的时间不一致的情况,与数据库对比可以发现,这里的时间戳与数据库时间刚好相差了 8 个小时,在实际生产中这种情况是不

一杯咖啡半杯糖的博客 3854

蓝牙学习笔记之HCI协议(一)

目录 协议浅述 HCI简介 HCI协议数据格式 HCI Command Packet HCI ACL Data Packet HCI Synchronous(SCO) Data Packet HCI Event Packet HCI命令和事件介绍 Inquiry command Write Local Name Command Read BD_ADDR Command H...

在云巅的博客 2万+

深入理解 Java Deque 的设计哲学

通过追踪 Doug Lea 与 Joshua Bloch 的设计轨迹,我们不难发现,即便是 JDK 核心 API 的设计,也是在“向下兼容”、“接口隔离”和“开发者习惯”之间不断博弈与取舍的过程。与其记住peek和pop异常处理的不同,不如彻底抛弃这种“模拟语义”,直接使用带有明确方向标识的First/Last组 API。这样可以在 Code Review 阶段消除由于null返回值或带来的隐患。需要抛异常的栈:统一使用addFirstgetFirst。不抛异常的栈:统一使用offerFirst。

dsgdauigfs的博客 626

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Java泛型实战:从类型擦除到PECS原则的深度解析

本文深度解析Java泛型的核心机制与应用实践,从类型擦除原理到PECS原则的实战应用。通过具体代码示例展示通配符的使用场景,揭示泛型在集合框架中的精妙设计,帮助开发者规避类型擦除陷阱并构建类型安全的API。特别针对泛型方法、泛型接口等高级特性提供实用解决方案。

weixin_34343308的博客 490

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Java设计模式实战解析:从SOLID原则到23种模式应用

面向对象设计原则是构建可维护、可扩展软件系统的基石,其中SOLID原则提供了核心指导。这些原则通过封装、继承和多态等机制,帮助开发者实现高内聚低耦合的代码结构,提升系统的灵活性和可测试性。在工程实践中,设计模式作为这些原则的具体实现模板,为解决常见设计问题提供了经过验证的最佳实践。例如,工厂模式通过抽象创建过程实现对象生成解耦,观察者模式则建立了对象间的高效事件通知机制。这些模式广泛应用于企业级开发、框架设计等场景,能有效管理复杂业务逻辑和系统组件协作。本文以Java为例,深入剖析创建型、结构型和行为型三大

weixin_33709609的博客 412

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Common Lisp专家Peter Seibel对Google公司首席Java架构师Joshua Bloch的访谈(摘一段)

API对设计流程的影响   Seibel:你设计软件的流程是什么样的?打开Emacs就开始写代码,然后改来改去直到程序写好?还是坐到沙发上拿着一打纸先列个提纲?   Bloch:很多年前,我在OOPSLA(译者注:面向对象编程、系统、语言和应用国际研讨会。)上作了一个演讲,题目是“如何设计一个好的API,以及这为什么很重要”。网上可以找到这个演讲的几个...

weixin_30508309的博客 130

阿里内部学习指南《Effective Java中文 第3版》程序员进阶必备

Java从1997年诞生到日趋完善,经过了20多年不断的发展壮大,已经拥有了近千万开发人员。如何编写出更清晰、更正确、更健壮且更易于重用的代码,是大家所追求的目标。 经典Jolt获奖作品《Effective Java》的第3版这本书,对上一版内容进行了彻底的更新,介绍了如何充分利用从泛型到枚举、从注解到自动装箱的各种特性,帮助读者更加有效地使用Java编程语言及其基本类库:java.lang. java.util和java.io,以及子包,如java.util. concurrent和java.util.

文章中资料均可获取,有需要请添加yunduoa2019即可 948

Effective Java核心要点与实战应用指南

Java编程语言作为企业级开发的主流选择,其设计模式与最佳实践对构建健壮系统至关重要。《Effective Java》作为Java开发者的经典读物,系统性地总结了90条编程准则,涵盖对象创建、类设计、泛型、并发等核心技术领域。理解这些原则不仅能提升代码质量,还能规避常见的性能陷阱与安全风险。例如静态工厂方法优化对象创建、Builder模式处理复杂构造、PECS原则规范泛型使用等实践,在电商系统、金融交易等高并发场景中尤为重要。通过掌握这些Java高级特性,开发者可以编写出更高效、更安全的应用程序,特别是在微

weixin_34198453的博客 447

前谷歌首席Java架构师谈如何设优秀的API~

随着近来软件规模的日益庞大,API编程接口的设计变的越来越重要。良好的接口设计可以降低系统各部分之间的相互依赖,提高组成单元的内聚性,降低组成单元间的耦合度,从而提高系统的维护性和稳定性。 Joshua Bloch是美国著名程序式设计师。他为Java平台设计并实现了许多的功能,是Google的首席Java架构师(Chief Java Architect)。他也是《Effective Java P

Jason的专栏 524

最近10年计算机专业图书中的50强

美国著名图书频道Book Pool集结最权威的62位作者评选出了最近10年计算机专业图书中的50强[原文]光这62位作者阵营就非常强大,我们熟悉的就有: Francesco Balena(Microsoft.NET框架程序设计,Visual Basic.NET语言描述作者) Bert Bates(Head First Design Patterns作者)

玄鐵劍 的專欄 1328

Java String不可变设计解析与面试要点

不可变对象是编程中的重要概念,指实例创建后状态不能被修改。Java中的String类采用不可变设计,通过final修饰字符数组和禁止继承等机制实现。这种设计带来线程安全、哈希缓存、内存优化等多重技术优势,特别适合作为HashMap键值或配置参数。从JVM角度看,字符串常量池复用机制直接依赖不可变性,而现代JDK的紧凑字符串优化进一步提升了内存效率。在Java面试中,String不可变问题能综合考察候选人对内存模型、API设计等核心知识的理解深度,是区分基础扎实程度的重要指标。实际开发中需注意与StringB

weixin_34194087的博客 504
上一篇: Bytebase 签约 Wallex,助其强化数据安全与合规性,实现精细的数据访问控制和数据脱敏
下一篇: 奥赛满分金牌得主出品,硅谷诞生超级AI码农
Bytebase
博客等级 码龄5年 1349粉丝 258原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值