如何设计好API

2023-11-02

“语言首先是写给人看的,只是恰巧(incidentally)能够运行” ——《计算机程序的构造和解释》。

好的API应对客户端友好,换言之就是能够直接通过其方法签名而理解它做的事情,而不用深入去阅读方法的实现,甚至深入阅读API所在的整个类。

单纯的介绍如何设计好API似乎如"海市蜃楼"般的虚无缥缈,因此本文从设计&实现的角度出发,针对我们在设计并实现API的过程中提出一些小意见。

首先回顾一下API方法的组成模块:

  • API注释

  • 访问修饰符

  • 返回值

  • 方法名称

  • 参数列表

  • 异常列表

  • 方法主体

针对API方法的组成模块,将提出几点小意见;可简单归纳为:“一个原则,三点建议,两个思考,三要五不要”。

在这里插入图片描述

一原则

最小知识原则(Least Knowledge Principle)

最小知识原则,或称迪米特法则;是一种面向对象程序设计的指导原则,它描述了一种保持代码松耦合的策略。

它描述的是一个软件实体应尽可能少地与其他实体发生相互作用;这里的软件实体是一个广义的概念,可指代系统、类、模块、对象、函数、变量等。

用更加通俗的语言来描述就是:“不应该有直接依赖关系的类之间,不要有依赖;有依赖关系的类之间,尽量只依赖必要的接口”。(“软件实体”替换成“类”)

用一个例子来描述,DatabaseConfig类为数据库实体类,用以描述数据源信息;JdbcUtils类用以封装一些基础的JDBC操作。

/**
 * 数据库实体对象
 * @author coder小奇
 * @date 2020/9/6
 **/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DatabaseConfig {
   

    private long id;

    private int clusterId;

    private String host;

    private String port;

    private String dbName;

    private String dbType;

    private String jdbcUrl;

    private String username;

    private String password;

    private String dbOwner;

    private String createUser;

    private String updateUser;

    private String createTime;

    private String updateTime;

}

/**
 * jdbc底层操作
 * 执行SQL 包装数据等
 * @author codeer小奇

 * @date 2020/9/6
 **/
public class JdbcUtils {
   
    // 获取jdbc Connection
    public static Connection getConnection(@NonNull DatabaseConfig databaseConfig) throws ClassNotFoundException, SQLException {
   
        DbType dbType = DbType.valueOf(databaseConfig.getDbType());
        Class.forName(dbType.getDriver());
        return DriverManager.getConnection(databaseConfig.getJdbcUrl(), databaseConfig.getUsername(), databaseConfig.getPassword());
    }
}

这段代码虽然能满足业务需求,但有些地方可以做到更好。JdbcUtils作为一个底层的基础服务类,希望做到尽可能的通用,而不只是支持DatabaseConfig数据源;其次从另外一个角度来看,DatabaseConfig实体中有太多的属性字段,getConnectionAPI到底依赖哪个字段难以确认;所以getConnectionAPI的设计一定程度上违背了 最小知识原则,依赖了不该有的直接依赖关系的DatasourceConfig类。

我们可对JdbcUtilsgetConnection方法作以改造,使其满足最小知识原则。我们应该只提供getConnection需要的信息。

public static Connection getConnection(@NonNull String driver, @NonNull String jdbcUrl, @NonNull String username,
                                           @NonNull String password)
            throws ClassNotFoundException, SQLException {
   
        Class.forName(driver);
        return DriverManager.getConnection(jdbcUrl, username, password);
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何设计好API 的相关文章

  • Spring Batch 多线程 - 如何使每个线程读取唯一的记录?

    这个问题在很多论坛上都被问过很多次了 但我没有看到适合我的答案 我正在尝试在我的 Spring Batch 实现中实现多线程步骤 有一个包含 100k 条记录的临时表 想要在 10 个线程中处理它 每个线程的提交间隔为 300 因此在任何时
  • Java JDBC:更改表

    我希望对此表进行以下修改 添加 状态列 varchar 20 日期列 时间戳 我不确定该怎么做 String createTable Create table aircraft aircraftNumber int airLineCompa
  • INSERT..RETURNING 在 JOOQ 中不起作用

    我有一个 MariaDB 数据库 我正在尝试在表中插入一行users 它有一个生成的id我想在插入后得到它 我见过this http www jooq org doc 3 8 manual sql building sql statemen
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • 列出jshell中所有活动的方法

    是否有任何命令可以打印当前 jshell 会话中所有新创建的方法 类似的东西 list但仅适用于方法 您正在寻找命令 methods all 它会打印所有方法 包括启动 JShell 时添加的方法 以及失败 被覆盖或删除的方法 对于您声明的
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • Spring Data JPA 应用排序、分页以及 where 子句

    我目前正在使用 Spring JPA 并利用此处所述的排序和分页 如何通过Spring data JPA通过排序和可分页查询数据 https stackoverflow com questions 10527124 how to query
  • 斯坦福 NLP - 处理文件列表时 OpenIE 内存不足

    我正在尝试使用斯坦福 CoreNLP 中的 OpenIE 工具从多个文件中提取信息 当多个文件 而不是一个 传递到输入时 它会给出内存不足错误 All files have been queued awaiting termination
  • 禁止的软件包名称:java

    我尝试从数据库名称为 jaane 用户名 Hello 和密码 hello 获取数据 错误 java lang SecurityException Prohibited package name java at java lang Class
  • Java TestNG 与跨多个测试的数据驱动测试

    我正在电子商务平台中测试一系列商店 每个商店都有一系列属性 我正在考虑对其进行自动化测试 是否有可能有一个数据提供者在整个测试套件中提供数据 而不仅仅是 TestNG 中的测试 我尝试不使用 testNG xml 文件作为机制 因为这些属性
  • 如何将 pfx 文件转换为 jks,然后通过使用 wsdl 生成的类来使用它来签署传出的肥皂请求

    我正在寻找一个代码示例 该示例演示如何使用 PFX 证书通过 SSL 访问安全 Web 服务 我有证书及其密码 我首先使用下面提到的命令创建一个 KeyStore 实例 keytool importkeystore destkeystore
  • 为什么HashMap不能保证map的顺序随着时间的推移保持不变

    我在这里阅读有关 Hashmap 和 Hashtable 之间的区别 http javarevisited blogspot sg 2010 10 difference Between hashmap and html http javar
  • 如何在控制器、服务和存储库模式中使用 DTO

    我正在遵循控制器 服务和存储库模式 我只是想知道 DTO 在哪里出现 控制器应该只接收 DTO 吗 我的理解是您不希望外界了解底层域模型 从领域模型到 DTO 的转换应该发生在控制器层还是服务层 在今天使用 Spring MVC 和交互式
  • AWS 无法从 START_OBJECT 中反序列化 java.lang.String 实例

    我创建了一个 Lambda 函数 我想在 API 网关的帮助下通过 URL 访问它 我已经把一切都设置好了 我还创建了一个application jsonAPI Gateway 中的正文映射模板如下所示 input input params
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • Firebase 添加新节点

    如何将这些节点放入用户节点中 并创建另一个节点来存储帖子 我的数据库参考 databaseReference child user getUid setValue userInformations 您需要使用以下代码 databaseRef
  • 按日期对 RecyclerView 进行排序

    我正在尝试按日期对 RecyclerView 进行排序 但我尝试了太多的事情 我不知道现在该尝试什么 问题就出在这条线上适配器 notifyDataSetChanged 因为如果我不放 不会显示错误 但也不会更新 recyclerview
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j

随机推荐

  • react 是怎么运行的?

    react 是怎么运行的 import React from react import ReactDOM from react dom const App div style color 000000 hello world div con
  • 如何完全删除,删的可以重新下载新的MySQL·

    第一步 快捷键win r输入regedit进入注册表 找到HKEY LOCAL MACHINE SYSTEM ControlSet001 Services Eventlog Application MySQL文件夹删除 删除HKEY LOC
  • 程序员精进之路:性能调优利器--火焰图

    本文主要分享火焰图使用技巧 介绍 systemtap 的原理机制 如何使用火焰图快速定位性能问题原因 同时加深对 systemtap 的理解 让我们回想一下 曾经作为编程新手的我们是如何调优程序的 通常是在没有数据的情况下依靠主观臆断来瞎蒙
  • Docker 镜像使用基本操作

    今天我将围绕 Docker 核心概念镜像展开 首先重点讲解一下镜像的基本操作 然后介绍一下镜像的实现原理 首先说明 咱们本课时的镜像均指 Docker 镜像 你是否还记得镜像是什么 我们先回顾一下 镜像是一个只读的 Docker 容器模板
  • 作为网络工程师,你知道私有IP地址范围吗?

    RFC 1918定义了私有IP的范围私有 内网 IP地址范围 A类 10 0 0 0 10 255 255 255B类 172 16 0 0 172 31 255 255C类 192 168 0 0192 168 255 255 提高 RF
  • C++ string的用法和例子

    https blog csdn net tengfei461807914 article details 52203202 string是C 标准库的一个重要的部分 主要用于字符串处理 可以使用输入输出流方式直接进行操作 也可以通过文件等手
  • LinearAlgebraMIT_6_ColumnSpaceAndNullSpace

    这节课的两个重点是column space列空间和null space零空间 x 1 pre multiply left multiply and post multiply right multiply 对于pre multiply le
  • 了解MQ和安装使用RabbitMQ

    什么是消息队列 本质是一个队列 队列中出存放的是跨进程的通信机制 用于上下游传递消息 MQ是常见的上下游 逻辑解耦 物理解耦 的消息通信服务 在使用MQ之后 消息发送上只需要依赖MQ 不用依赖其他服务 功能 1 流量削峰 举个例子 系统最多
  • 最新抖音快手小红书西瓜全平台解析接口api开发文档

    简介 从短视频平台APP中复制出来的分享链接 通过接口获取或通过主页在线一键解析获取短视频中的 视频标题 视频封面 无水印视频地址 图集列表等参数信息 接口地址 https eeapi cn 返回格式 JSON 请求方式 GET 客户UId
  • 常见的Java框架有哪些?

    作为一名合格的Java开发工程师 不仅需要了解开发技术 还需要了解清楚Java主流框架信息 那么常见的Java框架有哪些 常见的Java框架有哪些 1 Spring框架 Spring框架是现在Java后端框架家族里面最强大的一个 拥有IOC
  • 【PTA】约瑟夫环问题

    n个小孩围成一圈 从第一个小孩开始从1到m报数 报到m的小孩出列 下一个小孩继续从1开始报数 出列的小孩不参与报数 问小孩的出列顺序 import java util public class Main public static void
  • 【Proteus仿真】【51单片机】简易信号发生器设计

    文章目录 一 主要功能 二 使用方法 三 硬件资源 四 软件设计 1 主要代码 五 实验现象 联系作者 一 主要功能 1 可生成常用波形 方波 锯齿波 三角波 阶梯波 正玄波 2 可通过按键切换不同波形输出 二 使用方法 系统运行后 按下K
  • 如何在git中修改用户名和密码

    随着开源软件的不断发展 git已成为了极其流行的版本控制系统 git是一个非常强大的工具 引入了一系列的概念和机制 便于软件工程师跟踪他们的代码变化 这篇文章将会谈论如何在git中修改用户名和密码 git是什么 Git是一个由Linus T
  • 分治法-Strassen-矩阵乘法详细代码

    public class Matrix 初始化一个随机nxn阶矩阵 public static int initializationMatrix int n int result new int n n for int i 0 i lt n
  • 全网最全Android Framework框架总结,Android如何入门Framework层

    每一个Android开发 基本都了解或者学习过系统的知识 一是因为国内软件行业内卷 找工作时 面试造火箭 工作拧螺丝 的局面导致的 另一方面 从客观角度来讲 学习Android系统 Framework 等源代码或者其工作方式也可以提升我们
  • Nginx系列教程(五)

    冷备份是定期复制 不能保证数据可用性 热备份又分为异步热备和同步热备 异步热备是指 多份数据副本的写入操作异步完成 同步热备是指 多份数据副本的写入操作同时完成 服务层面 失效转移 如某块磁盘损坏 将从备份的磁盘读取数据 首先是已经提前做好
  • 九问国产操作系统,九大掌门人万字回应!

    整理 屠敏 责编 唐小引 出品 CSDN ID CSDNnews 在国产基础软件发展的多年间 众多摸着石头过河的先行者无数次感叹 蜀道之难 难于上青天 不仅包含数据库 中间件 芯片 操作系统等核心软硬件研发 也覆盖了每种技术领域的生态建设
  • 【反序列化漏洞-01】序列化与反序列化概述

    为什么要序列化 百度百科上关于序列化的定义是 将对象的状态信息转换为可以存储或传输的形式 字符串 的过程 在序列化期间 对象将其当前状态写入到临时或持久性存储区 非关系型键值对形式的数据库Redis 与数组类似 以后 可以通过从存储区中读取
  • VMWARE虚拟机网络环境配置

    VMWARE虚拟机网络环境配置 1 查看物理机ip信息 命令 ipconfig 2 配置网络适配器环境 点击 控制面板 选择 网络和Internet 点击 查看网络状态和任务 点击 更改适配器设置 选择VMnet8那个适配器 邮件选择 属性
  • 如何设计好API

    语言首先是写给人看的 只是恰巧 incidentally 能够运行 计算机程序的构造和解释 好的API应对客户端友好 换言之就是能够直接通过其方法签名而理解它做的事情 而不用深入去阅读方法的实现 甚至深入阅读API所在的整个类 单纯的介绍如