2013-04-25 115 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