使用带有“旧”对象引用的Builder模式创建新对象

我正在使用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模式对这种方法并不是很有用?

编辑:(在Eugene发表评论后)

想想,我明白了:

 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; } } 

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

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

编辑

您需要阅读有关构建器模式的更多信息,以便更好地掌握它是什么以及是否真的需要它。

一般的想法是,当您有可选元素时使用Builder模式。 有效的Java Item 2是你最好的朋友。

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

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

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

 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 

我会把它改成

  public class MsProjectTaskData { private boolean transfered; private String request; public static class Builder { private boolean transfered = false; private String request; public Builder() { // empty } public Builder(MsProjectTaskData old) { this.request(old.request); this.transfered(old.transfered); } public Builder request(String val) { request = val; return this; } public Builder transfered(boolean val) { transfered = val; return this; } public MsProjectTaskData build() { return new MsProjectTaskData(this); } } private MsProjectTaskData(Builder builder) { transfered = builder.transfered; request = builder.request; } } 

并像这样使用

 MsProjectTaskData data = new MsProjectTaskData.Builder().transfered(true).request("request").build(); MsProjectTaskData changedData = new MsProjectTaskData.Builder(data).transfered(false).request("changeRequest").build(); MsProjectTaskData sameData = new MsProjectTaskData.Builder(data).build(); 

我冒昧地将布尔值更改为“已转移”,我觉得它更容易理解