2013-04-25 85 views
4

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

我可以创建生成一个新的对象是这样的:

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

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

+0

你在说什么'旧'对象引用?向'build()'方法中添加一个参数。这最终与复制构造函数具有相同的效果。 – 2013-04-25 13:57:25

+0

旧对象引用表示MsProjectTaskData的“旧”对象。我想用在withTransfered(true)方法中设置的新值来克隆这个对象。 – sk2212 2013-04-25 14:00:08

+0

在这种特殊情况下,一个简单的setTransfered()可以完成这项工作。如果你的目标是熟悉builder模式及其实现,我想你必须去找一个更好的例子。你在这里做什么看起来更像是原型。 – Fildor 2013-04-25 14:00:43

回答

11

使Builder构造函数将“old”对象作为参数并将其设置为新的对象。

编辑

你需要阅读更多的关于建造者模式它是什么,以获得更好的把握,如果你真的需要它。

总的想法是,当你有可选元素时使用Builder模式。有效的Java项目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 
+0

你能提供一些代码吗?我没有得到它的工作:(。 – sk2212 2013-04-25 14:30:16

+0

@ sk2212看到我的编辑 – Eugene 2013-04-26 07:11:05

+0

谢谢,这有效!那么你说,也许使用Builder模式在这里没有什么用处,目前我尝试改变我当前项目的可变对象如果我需要更改这个对象的属性并将其放回到容器数组列表中,这并不是那么容易。 – sk2212 2013-04-26 07:56:53

0

我将其更改为

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(); 

使用我拿了自由将布尔变成“转移”,我觉得这很容易理解

+0

嗯...但我有10个更多的变量,如“请求”?我必须为每个变量创建一个新的Builder方法,这并不是真的必要。 – sk2212 2013-04-25 14:31:33