为什么强烈鼓励使用构建器模式,而不是直接在 Java 中实施 fluent API?

Why is the usage of builder pattern highly encouraged instead of a straight forward implementation of fluent API in Java?

考虑以下构建器模式示例:

import java.util.Objects;

public class Vehicle {
    private final String brand;
    private final int wheels;
    private final int doors;
    private final int maxSpeed;

    private Vehicle(Builder builder) {
        this.brand = Objects.requireNonNull(builder.brand, "brand");
        this.wheels = Objects.requireNonNull(builder.wheels, "wheels");
        this.doors = Objects.requireNonNull(builder.doors, "doors");
        this.maxSpeed = Objects.requireNonNull(builder.maxSpeed, "maxSpeed");
    }

    public static Builder builder() {
        return new Builder();
    }

    public void display() {
        System.out.println("brand = " + getBrand());
        System.out.println("wheels = " + getWheels());
        System.out.println("doors = " + getDoors());
        System.out.println("maxSpeed = " + getMaxSpeed());
    }

    public String getBrand() {
        return brand;
    }

    public int getWheels() {
        return wheels;
    }

    public int getDoors() {
        return doors;
    }

    public int getMaxSpeed() {
        return maxSpeed;
    }

    public static class Builder {
        private String brand;
        private Integer wheels;
        private Integer doors;
        private Integer maxSpeed;

        Builder() {
        }

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

        public Builder setWheels(int wheels) {
            this.wheels = wheels;
            return this;
        }

        public Builder setDoors(int doors) {
            this.doors = doors;
            return this;
        }

        public Builder setMaxSpeed(int maxSpeed) {
            this.maxSpeed = maxSpeed;
            return this;
        }

        public Builder of(Vehicle vehicle) {
            this.brand = vehicle.brand;
            this.wheels = vehicle.wheels;
            this.doors = vehicle.doors;
            this.maxSpeed = vehicle.maxSpeed;
            return this;
        }

        public Vehicle build() {
            return new Vehicle(this);
        }
    }
}

当我们创建一个 Vehicle 类型的对象时,我们有:

Vehicle vehicle = new Vehicle.Builder()
                .setBrand("Mercedes")
                .setWheels(4)
                .setDoors(4)
                .setMaxSpeed(250)
                .build();

另一方面,可以在 class Vehicle 的每个 setter 中简单地 return this,例如:

public class Vehicle {
    private final String brand;
    private final int wheels;
    private final int doors;
    private final int maxSpeed;

    private Vehicle(String brand, int wheels, int doors, int maxSpeed){
        this.brand = brand;
        this.wheels = wheels;
        this.doors = doors;
        this.maxSpeed = maxSpeed;
    }

    public Vehicle() {
    }

    public String getBrand() {
        return brand;
    }

    public int getWheels() {
        return wheels;
    }

    public int getDoors() {
        return doors;
    }

    public int getMaxSpeed() {
        return maxSpeed;
    }

    public Vehicle setBrand(String brand) {
        this.brand = brand;
        return this;
    }

    public Vehicle setWheels(int wheels) {
        this.wheels = wheels;
        return this;
    }

    public Vehicle setDoors(int doors) {
        this.doors = doors;
        return this;
    }

    public Vehicle setMaxSpeed(int maxSpeed) {
        this.maxSpeed = maxSpeed;
        return this;
    }

    public void display() {
        System.out.println("brand = " + getBrand());
        System.out.println("wheels = " + getWheels());
        System.out.println("doors = " + getDoors());
        System.out.println("maxSpeed = " + getMaxSpeed());
    }
}

我们可以通过以下方式创建 Vehicle 类型的对象:

Vehicle vehicle = new Vehicle();
vehicle.setBrand("Mercedes")
       .setDoors(4)
       .setMaxSpeed(250);

在我看来,与传统的构建器模式相比,第二种方法产生的代码更少。尽管如此,我知道许多图书馆改用构建器模式。那么,与第二种方法相比,构建器模式的优点是什么,第二种方法实际上没有那么复杂?

构建器模式与流畅模式相比的一些好处api:

  1. Builder 不仅可以 return Vehicle class,还可以 class SomeClass extends Vehicle
  2. 您可以将自定义的复杂逻辑添加到构建方法中(验证、开关实现等)
  3. 您不能在没有必要属性的情况下创建 Vehicle

但是如果您不需要这些好处,使用您的方法绝对是正常的。一些图书馆使用那个