“语言首先是写给人看的,只是恰巧(incidentally)能够运行” ——《计算机程序的构造和解释》。
好的API应对客户端友好,换言之就是能够直接通过其方法签名而理解它做的事情,而不用深入去阅读方法的实现,甚至深入阅读API所在的整个类。
单纯的介绍如何设计好API似乎如"海市蜃楼"般的虚无缥缈,因此本文从设计&实现的角度出发,针对我们在设计并实现API的过程中提出一些小意见。
首先回顾一下API方法的组成模块:
-
API注释
-
访问修饰符
-
返回值
-
方法名称
-
参数列表
-
异常列表
-
方法主体
针对API方法的组成模块,将提出几点小意见;可简单归纳为:“一个原则,三点建议,两个思考,三要五不要”。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200927120512773.png?x-oss-process=image)
一原则
最小知识原则(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
实体中有太多的属性字段,getConnection
API到底依赖哪个字段难以确认;所以getConnection
API的设计一定程度上违背了 最小知识原则
,依赖了不该有的直接依赖关系的DatasourceConfig
类。
我们可对JdbcUtils
的getConnection
方法作以改造,使其满足最小知识原则。我们应该只提供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);