Java中的流畅接口和构建模式之间的区别


流畅接口Fluent Interface 是一种面向对象的 API 设计,它允许我们以可读和直观的方式将方法调用链接在一起。要实现它,我们需要声明从同一类返回对象的方法。因此,我们将能够将多个方法调用链接在一起。该模式通常用于构建 DSL(领域特定语言)。

例如,Java8 的Stream API使用流畅的接口模式,允许用户以非常声明的方式操作数据流。让我们看一个简单的例子,观察在每一步之后如何返回一个新的Stream :

Stream<Integer> numbers = Stream.of(1,3,4,5,6,7,8,9,10);

Stream<String> processedNumbers = numbers.distinct()
  .filter(nr -> nr % 2 == 0)
  .skip(1)
  .limit(4)
  .map(nr -> "#" + nr)
  .peek(nr -> System.out.println(nr));

String result = processedNumbers.collect(Collectors.joining(
", "));

这是一个返回String 的收集器:
首先我们需要创建实现流畅 API 模式的对象,在我们的例子中,这是通过静态方法Stream.of()实现的。在此之后,我们通过其公共 API 进行操作,我们可以注意到每个方法如何返回相同的类。我们以一个返回不同类型的方法结束。

构建器设计模式(Builder Pattern )是一种创建型设计模式,它将复杂对象的构造与其表示分离。

Builder类实现了流畅的接口模式,并允许逐步创建对象。

User.Builder userBuilder = User.builder();

userBuilder = userBuilder
  .firstName("John")
  .lastName(
"Doe")
  .email(
"jd@gmail.com")
  .username(
"jd_2000")
  .id(1234L);

User user = userBuilder.build();

流畅的界面设计模式是由User.Builder类实现的,该类是使用User.builder()方法创建的。在此之后,我们链接多个方法调用,指定User的各种属性,这些步骤中的每一个都返回相同的类型:一个User.Builder。最后,我们通过实例化并返回User 的build()方法调用退出流畅的界面。

构建者模式是流畅的API模式的唯一可能的实现。

如何实现?
1、如果我们想创建一个具有流畅接口的对象,我们需要考虑不变性方面。

上一节中的User.Builder不是一个不可变的对象,它正在改变其内部状态,总是返回相同的实例——它自己:

public static class Builder {
    private String firstName;
    private String lastName;
    private String email;
    private String username;
    private Long id;

    public Builder firstName(String firstName) {
        this.firstName = firstName;
    return this;
    }

    public Builder lastName(String lastName) {
        this.lastName = lastName;
    return this;
    }

    // other methods

    public User build() {
         return new User(firstName, lastName, email, username, id);
    }
}

2、当我们构建流畅的接口时,我们必须关注 API 的公共方法数量。我们可能会想添加越来越多的方法,从而产生一个巨大的对象。

解决大接口的问题,拆分我们的 API 以遵守SOLID接口隔离原则。