Java 接口规范与最佳实践

版权声明:未经允许,不得转载 https://blog.csdn.net/kangkanglou/article/details/83987464
  • 可理解

  • 文档完善

  • 格式统一:这里涉及很多方面,包括:接口返回类型、命名规则以及参数顺序

    • 在我们所有的API方法中,要么是全是getXYZ()格式,要么全是xyz(),最好不要两种格式都有。
    • 假设我们有方法重载,原始方法接受参数Object...,重载方法接受参数为Collection<? extends Object>,那么,重载方法不能部分可见
  • 恰到好处的适用:作为一名开发人员,很自然的一种本能就是尽可能的开发提供大而全的服务接口,但这样做可能会带来两个问题:1. 接口过于笨重,接口调用方可能需要额外消化一些不必要的业务逻辑来理解接口实际含义。2. 接口暴露越多,维护负担越重。因此,所谓恰到好处的适用就是这个含义:

    • 接口应功能单一,并且能正确响应
    • 了解接口潜在用户及目标
  • 一定范围、时期的使用受限:我们都知道开发接口非常容易,但事情远非一蹴而就那么简单,接口背后带来的是服务承诺。接口的服务成本依赖于很多因素:项目的实际情况以及社区本身,比如,有些项目可能非常乐于变更,但有些项目(比如JDK)则期待尽量保持稳定,这是两种极端状态,但,对于绝大部分项目来说,基本上都处于中间状态,惯例做法是通过一种语义化的版本管理方式实现接口的持续演变,即在接口从主版本更新删除之前,首先进行废弃处理(即我们常见的deprecate标识)。对于某些少部分项目来说,他们处理的方式更加多样,项目中会包含多种接口标识:比如:实验性版本的、Beta版本的、预览功能性的,这么做的目的是在最终接口确定之前,可以真实的收到各种版本接口的真实使用反馈,通常做法是在这些不同的版本接口上添加@Deprecated注解,当最终的服务接口确认发布之后,再删除这些中间服务接口。

  • 可变的:对于我们对外暴露的每一个接口,这都是一种服务承诺,既然是承诺,那么都有可能未来让我们自己为难或者尴尬的境地,所以,我们必须以发展前瞻的眼光来审视未来可能的SDK版本更新中更广泛的上下文环境中对接口所带来的影响。

  • 防止信息泄漏:避免接口实现类或者外部依赖类通过公共接口暴露出去(所谓暴露出去可能有两种方式:作为返回类型、作为参数类型),通常有以下两种方式来避免信息泄露:

    • 所有实现类均置于impl包中,此包下的所有类均不会出现在JavaDoc中,如果接口基于JDK1.9或者以上的版本开发,可以通过模块的方式排除目标类集合
    • 确保所有实现类的访问修饰符为package-private,即类定义不包含任何访问修饰符。
  • 正确理解protected含义:Java中的protected关键字经常被误用或者说滥用,简单来说,protected主要用于子类之间,而public则主要用于对外接口。事实上protected关键字会影响接口类的行为,进而导致本不应暴露的内部私有方法暴露成protected或者public类型。

  • 刻意继承:当我们在开发一个接口时,我们必须在功能性、灵活性和未来的可发展性、可持续性之间作一个平衡,一种常见的做法是使用final关键字,一旦标识一个方法或者类为final类型,我们就是要明确的告诉开发人员,不要去扩展或者重写这些特殊的类或者方法。final关键字对我们非常有用,毕竟我们的接口并非十全十美,与其受困于在老的版本中不停的解决问题,还不如另辟蹊径升级接口补丁,这样的话,我们只会引入新的问题,理想情况下,当接口调用方发现final标识,他们甚至可以直接与接口方直接沟通讨论,直至达到更加完美的接口服务方案,final关键字可以在后续的正式发布版本中剔除,但不建议在已经发布的接口中使用final关键字。

  • 向后兼容:在我们的日常接口实践中,当我们遇见新的需求或者问题时,好的做法是新增一个接口,但不推荐删除或者修改现有的接口。这么做的主要目的是向后兼容,这也很容易理解,当我们删除或者修改一个现有接口时,在用户升级至下个发布之前,我们其实就隐含带来了破坏用户原有代码正常调用的风险。但有时候,我们需要实现接口向后不兼容(比如,原有接口设计错误),一般我们可以使用@Deprecated,但通常的做法是使用semantic versioning策略。

  • 正确的使用Optional:JDK1.8引入的Optional关键字为我们减少NPE错误提供了一种可能,当方法返回为Optional它可以确保返回值不为NULL,那么在这种场景下,就需要由调用方来确认返回值中是否包含元素或者为空。但注意:

    • 不要返回Optional<Collection<T>>,这种可以简洁的以Collection<T>形式来表示
    • 不要在返回类型为Optional的方法中返回null
  • 不要返回null值billion-dollar mistake,在Java中较之null返回值,针对不同的返回类型,我们都有更好的选择:

RETURN TYPE NON-NULL RETURN VALUE
String “” (An empty string)
List / Set Map / Iterator Use the Collections class, e.g. Collections.emptyList()
Stream Stream.empty()
Array Return an empty, zero-length array
All other types Consider using Optional (but read the Optional section below first)

https://dzone.com/refcardz/java-api-best-practices?chapter=1

猜你喜欢

转载自blog.csdn.net/kangkanglou/article/details/83987464