Java 8的API设计原则

作者: a13ed6c7cc5e | 来源:发表于2019-04-19 16:04 被阅读1次

掌握的Java API 8设计,才能确保客户端代码可以使用lambda表达式访问API。 一个好的API的设计需要仔细思考和大量的经验。因为一旦一个API公布,从一开始就贯彻坚定的承诺是非常重要。公共API,就像钻石,永远留传。 你只有一次得到它的机会,所以给她最好的。

Java 8的API设计原则

API结合平衡了两个世界:坚定的和精确的承诺;以及具有高度的灵活性。下面是清单:

如果一个值缺了不要返回Null

不一致的空值处理(导致无处不在的NullPointerException异常)是Java应用程序历史上最大错误的唯一来源。 一些开发者认为引进null的概念是在计算机科学领域有史以来最严重的错误之一。 幸运的是,解决Java空值处理问题的第一步是Java 8中引入的Optional。 确保可以返回一个可选的对象,而不是null。

这样做:

public Optional<String> getComment() { return Optional.ofNullable(comment); } 

不要这样做:

public String getComment() { return comment; // comment is nullable } 

不要用数组将值在API之间传递

Java5引入枚举Enum类型,其方法values()是返回所有枚举元素值数组,每次进行values()调用会在内部复制一份数组,这导致差性能和客户端代码差可用性。

如果返回的是一个不可修改的List就好得多,比如Stream,如果API返回元素集合,最好返回的是只读类型。

可以这样做:

public Stream<String> comments() {
 return Stream.of(comments);
}

不要这样做:

public String[] comments() {
 return comments; // Exposes the backing array!
}

提供静态接口方法实现对象创建的单一入口

避免客户端代码直接选择接口实现类,这会造成紧耦合。

这样做:

Point point = Point.of(1,2);

不要这样做:

Point point = new PointImpl(1,2);

使用函数接口和Lambda而不是继承实现组合

为了避免继承API造成客户端代码与API紧耦合,考虑使用静态接口方法实现组合。

这样做:

Reader reader = Reader.builder()
 .withErrorHandler(IOException::printStackTrace)
 .build();

不要这样做:

Reader reader = new AbstractReader() {
 @Override
 public void handleError(IOException ioe) {
 ioe. printStackTrace();
 }
}

确保增加@FunctionalInterface元注解到函数接口中

使用@FunctionalInterface可以让API用户使用Lambda实现你的函数接口。

这样做:

@FunctionalInterface
public interface CircleSegmentConstructor {
 CircleSegment apply(Point cntr, Point p, double ang);
 // abstract methods cannot be added
}

不要这样做:

public interface CircleSegmentConstructor {
 CircleSegment apply(Point cntr, Point p, double ang);
 // abstract methods may be accidently added later
}

避免使用函数接口作为参数过载方法

如果有多个函数有相同名称,都是将函数化接口作为参数,那么会造成客户端创建lambda混乱。

不要这样做:

public interface Point {
 add(Function<Point, String> renderer);
 add(Predicate<Point> logCondition);
}

这样做:

public interface Point {
 addRenderer(Function<Point, String> renderer);
 addLogCondition(Predicate<Point> logCondition);
}

后者客户端可以使用 point.add(p -> p + “ lambda”) 调用。

避免过度使用接口中默认方法

默认方法有应该是短和“根本”的功能,不要加入太多内容。

不要这样做:

public interface Line {
 Point start();
 Point end();
 default int length() {
 int deltaX = start().x() - end().x();
 int deltaY = start().y() - end().y();

 return (int) Math.sqrt(
 deltaX * deltaX + deltaY * deltaY
 );
 }
}

这样做:

public interface Line {
 Point start();
 Point end();
 int length();
}

确保API方法在被执行前检查参数不变性

不要这样直接调用:

public void addToSegment(Segment segment, Point point) {
 segment.add(point);
}

增加必要的检查:

public void addToSegment(Segment segment, Point point) {
 Objects.requireNonNull(segment);
 Objects.requireNonNull(point);
 segment.add(point);
}

不要简单调用Optional.get()
Optional.get()其实是Optional.getOrThrow(),在get之前检查一下,这样不会抛出exception
这样做:

Optional<String> comment = 
// 某个 Optional值
 String guiText = comment .map(c -> "Comment: " + c) .orElse("");

相关文章

  • Java 8的API设计原则

    掌握的Java API 8设计,才能确保客户端代码可以使用lambda表达式访问API。 一个好的API的设计需要...

  • k8s资源管理概念

    Kubernetes 资源管理k8s的设计理念—API设计原则• 所有API应该是声明式的。• API对象是彼此互...

  • java8-新的日期API

    背景 java的日期和时间API设计不理想,java8引入新的时间和日期API就是为了解决这个问题。 java8引...

  • API设计

    API设计 Google API 设计思想 1、设计 API设计原则简单可用一致 HTTP 常用方法get 获...

  • jdk8 API文档

    API 文档 java SE 8 API 文档 jdk-8-apidocs 在线版 java SE 目录 java...

  • JVM虚拟机(1) 走进Java

    Java JDK Java程序设计语言 + Java虚拟机 + Java API类库 JRE Java API类库...

  • 美颜Java

    从原生的Java API创建线程谈起,讲述Scala对「控制结构」抽象的设计与实现. 创建线程 在Java8之前,...

  • Java 8 API 示例:字符串、数值、算术和文件

    Java 8 API 示例:字符串、数值、算术和文件 原文:Java 8 API by Example: Stri...

  • Java 8 - New Date/Time API

    Java 8 - New Date/Time API 1 Java 8-概述2 Java 8 - Lambda表达...

  • HttpMessageConverter是这样转换数据的

    Java Web 人员经常要设计 RESTful API(如何设计好的RESTful API),通过 json 数...

网友评论

    本文标题:Java 8的API设计原则

    本文链接:https://www.haomeiwen.com/subject/cefcgqtx.html