嵌套的静态构建器类,对其管道的进一步说明

时间:2011-09-16 08:37:17

标签: java design-patterns builder effective-java

public class MyPojo{
    String required;
    Integer optionalOne;
    Integer optionalTwo;

    private MyPojo(Builder builder){
        this.required = builder.required
        this.optionalOne = builder.one;
        this.optionalTwo = builder.two;
    }

    public static class Builder{

        String required;
        Integer optionalOne =0;
        Integer optionalTwo =0;

        public Builder(String req){
            this.required = req;
            return this;
        }
        public Builder optionalOne(Integer one){
            this.one = one;
            return this;
        }
        public Builder optionalTwo(Integer two){
            this.two = two;
            return this;
        }
        public MyPojo build(){
            return new MyPojo(this);
        }
    }
}

然后像这样调用:

MyPojo myPojo = new MyPojo.Builder("req").optionalOne(1).optionalTwo(2).build();

哪一个都很可爱,但我不了解几个部分。

在调用语句中有一个 New 语句,在build()方法中有一个,但是只创建了一个新对象?

另外,如果我再次拨打电话,没有第二个可选的参数:

MyPojo myPojo = new MyPojo.Builder("req").optionalOne(1).build();

为什么optionalTwo会恢复为默认值(零)。并且不保留第一次传递的值(2),它是一个静态类,所以在所有MyPojos之间共享一个实例?

2 个答案:

答案 0 :(得分:3)

这一位:

 new MyPojo().Builder("req")

应该是:

 new MyPojo.Builder("req")

首先创建一个Builder,然后Build方法(最好是build btw)创建不可变对象。

如果您创建第二个实例,那么它与第一个实例完全分开。不要被被声明为static的Builder类所欺骗 - 这只是意味着Builder的实例没有与之关联的隐式“父”MyPojo类引用。单独的Builder个实例的字段仍然是完全独立的。

答案 1 :(得分:-1)

这里有几个错误。正如所写,它甚至没有编译。

查看Fluent Interface它应该如何工作。现在考虑

MyPojo myPojo = new MyPojo.Builder(req).optionalOne(1).optionalTwo(2).Build();

(这不是你所拥有的,这是你所拥有的)

这是它的工作原理:

  1. new MyPojo.Builder(req)创建一个MyPojo.Builder对象,并将传递的req分配给this.required
  2. .optionOne(1)将{1}分配给MyPojo.Builder.optionalOne。然后它返回相同的对象(return this)。这是关键,因为它允许下一步
  3. .optionOne(2)为前一次调用返回的MyPojo.Builder.optionalTwo对象分配2 MyPojo.Builder。请注意,我们仍在使用在步骤1中创建的相同Builder对象。再次返回this
  4. Build()调用Build上的Builder方法,后者又调用MyPojo构造函数。应该将此方法称为build以符合Java命名约定。
  5. 编辑:代码无法编译。 EDIT2:详细解释