Java实现构建器模式的最佳方法

rax*_*ell 14 java builder

以下哪项是实施构建器模式的更好方法?

1)使用对象构建而不是构建器中的所有属性(并在构建器构造器中创建它):

public class Person {
    private String firstName;
    // other properties ...

    private Person() {}

    // getters ...

    public static class Builder {
        // person object instead of all the person properties
        private Person person;

        public Builder() {
            person = new Person();
        }

        public Builder setFirstName(String firstName) {
            person.firstName = firstName;

            return this;
        }

        // other setters ...

        public Person build() {
            if (null == person.firstName) {
                throw new IllegalStateException("Invalid data.");
            }

            return person;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

2)直接在构建器中使用对象的属性来构建而不是对象(并在build()方法中创建它):

public class Person {
    private String firstName;
    // other properties ...

    private Person() {}

    // getters ...

    public static class Builder {
        // person properties instead of object
        private String firstName;
        // other properties ...

        public Builder() {}

        public Builder setFirstName(String firstName) {
            this.firstName = firstName;

            return this;
        }

        // other setters ...

        public Person build() {
            if (null == this.firstName) {
                throw new IllegalStateException("Invalid data.");
            }

            Person person = new Person();
            person.firstName = firstName;

            return person;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我更喜欢第一种方式,因为我认为有很多属性在构建器中重复它们是多余的.第一种方法有一些缺点吗?

提前谢谢,抱歉我的英语不好.

Jav*_*boy 9

小注意:是的,属性可能是重复,但它们有优势

详情如下:如果你看一下这里的细节.

Pizza pizza = new Pizza(12);
pizza.setCheese(true);
pizza.setPepperoni(true);
pizza.setBacon(true);
Run Code Online (Sandbox Code Playgroud)

这里的问题是因为对象是在几次调用中创建的,所以它的构造中途可能处于不一致状态.这还需要大量额外的努力来确保线程安全.

更好的选择是使用Builder Pattern.

请注意以下Builder中的方法以及相应的构造函数或父Pizza类 - 此处链接的完整代码

 public static class Builder {

    public Pizza build() {    // Notice this method
      return new Pizza(this);
    }
  }

  private Pizza(Builder builder) {  // Notice this Constructor
    size = builder.size;
    cheese = builder.cheese;
    pepperoni = builder.pepperoni;
    bacon = builder.bacon;
  }
Run Code Online (Sandbox Code Playgroud)