为什么强烈鼓励使用构建器模式而不是直接在 Java 中实现流畅的 API?

Tru*_*ong 1 java design-patterns builder

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

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Vehicle vehicle = new Vehicle.Builder()
                .setBrand("Mercedes")
                .setWheels(4)
                .setDoors(4)
                .setMaxSpeed(250)
                .build();
Run Code Online (Sandbox Code Playgroud)

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

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Vehicle vehicle = new Vehicle();
vehicle.setBrand("Mercedes")
       .setDoors(4)
       .setMaxSpeed(250);
Run Code Online (Sandbox Code Playgroud)

在我看来,第二种方法产生的代码比传统的构建器模式少。尽管如此,我知道许多库都使用构建器模式。那么,与第二种方法(实际上更简单)相比,构建器模式有哪些优点呢?

Use*_*123 5

与 Fluent api 相比,构建器模式的一些好处:

  1. Builder 不仅可以返回 Vehicle 类,还可以返回 SomeClass 扩展 Vehicle
  2. 您可以将自定义复杂逻辑添加到构建方法中(验证、开关实现等)
  3. 如果没有必要的属性,则无法创建车辆

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

  • 构建器模式也很有用,因为它允许构建的对象是不可变的,这有助于确保整体程序的正确性。 (2认同)