java api设计_Java 8的API设计原则

Java 8的API设计原则

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

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

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

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

这样做:

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

不要这样做:

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

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

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

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

可以这样做:

public Stream 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 renderer);

add(Predicate logCondition);

}

这样做:

public interface Point {

addRenderer(Function renderer);

addLogCondition(Predicate 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 comment =

// 某个 Optional值

String guiText = comment .map(c -> "Comment: " + c) .orElse("");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值