8

我正在玩 Builder 模式并被困在如何将新的“属性”添加到新创建的对象中:

public class MsProjectTaskData {
  private boolean isAlreadyTransfered;
  private String req;    

   public static class Builder {    
    private boolean isAlreadyTransfered = false;

    public Builder withTransfered(boolean val) {
        isAlreadyTransfered = val; 
        return this;
    }    
    public MsProjectTaskData build() {
        return new MsProjectTaskData(this);
    }
   }

   private MsProjectTaskData(Builder builder) {
     isAlreadyTransfered = builder.isAlreadyTransfered;
   }

  public MsProjectTaskData(String req) {
    this.req = req;
  }
}

我可以像这样使用 Builder 创建一个新对象:

MsProjectTaskData data = new MsProjectTaskData.Builder().withTransfered(true).build();

但是使用这种方法,req来自新创建对象的字符串会丢失(当然)。

是否有可能使用新的集合isAlreadyTransfered变量和来自“旧”对象的“旧”req字符串创建一个新对象?

也许我必须将旧对象引用传递给 Builder,但我不知道该怎么做。也许使用 Builder 模式对于这种方法并没有真正的用处?

编辑:(来自尤金的评论后)

想想,我明白了:

public static class Builder {   
 private boolean isAlreadyTransfered = false;
 private MsProjectTaskData data;

 public Builder(MsProjectTaskData data) {
     this.data = data;
 }

 public Builder withTransfered(boolean val) {
     isAlreadyTransfered = val; 
     data.setAlreadyTransfered(isAlreadyTransfered);
     return this;
 }   
 public MsProjectTaskData build() {
     return data;
 }
}

似乎工作或上面的代码有问题?我可以不加考虑地使用这种方法吗?

4

1 回答 1

17

使 Builder 构造函数将“旧”对象作为参数,并将您想要的任何内容设置为新对象。

编辑

您需要阅读更多关于构建器模式的内容,以便更好地了解它是什么以及您是否真的需要它。

一般的想法是当您有可选元素时使用构建器模式。Effective Java Item 2 是你最好的朋友。

对于您的类,如果您想从另一个对象构建一个对象并同时使用 Builder 模式,您

  1. 在 Builder 构造函数中传递“旧”对象
  2. fromOld创建一个方法等。

那看起来怎么样?我将只提供第一个,你可以自己弄清楚第二个。

class MsProjectTaskData {
    private final String firstname;
    private final String lastname;
    private final int age;

    private MsProjectTaskData(Builder builder){
        this.firstname = builder.firstname;
        this.lastname  = builder.lastname;
        this.age       = builder.age;
    }

    public static final class Builder{
        //fields that are REQUIRED must be private final
        private final String firstname;
        private final String lastname;

        //fields that are optional are not final
        private int age;

        public Builder(String firstname, String lastname){
            this.firstname = firstname;
            this.lastname  = lastname;
        }

        public Builder(MsProjectTaskData data){
            this.firstname = data.firstname; 
            this.lastname  = data.lastname;
        }

        public Builder age(int val){
            this.age = val; return this;
        }

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

    public String getFirstname() {
         return firstname;
    }

    public String getLastname() {
         return lastname;
    }

    public int getAge() {
         return age;
    }
}

以及如何从另一个对象创建一个对象:

   MsProjectTaskData.Builder builder = new MsProjectTaskData.Builder("Bob", "Smith");
   MsProjectTaskData oldObj = builder.age(23).build();
   MsProjectTaskData.Builder newBuilder = new MsProjectTaskData.Builder(oldObj);
   MsProjectTaskData newObj = newBuilder.age(57).build();
   System.out.println(newObj.getFirstname() + " " + newObj.getLastname() + " " + newObj.getAge()); // Bob Smith 57
于 2013-04-25T14:02:32.587 回答