2013-04-25 5 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; 
    } 
} 

я могу создать новый объект Builder, как это:

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

Но при таком подходе req строка из нового созданного объекта теряется (конечно).

Есть ли возможность создать новый объект с новым набором isAlreadyTransfered переменной и со «старой» строкой req из «старого» объекта?

Возможно, мне нужно передать старую ссылку на объект Builder, но я не знаю, как это сделать. Может быть, использование шаблона Builder не очень полезно для этого подхода?

EDIT: (После того, как комментарий от 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; 
} 
} 

Кажется, работает или что-то не так с кодом выше? Могу ли я использовать этот подход без рассмотрения?

+0

В какой «старой» ссылке на объект вы говорите? Добавьте параметр в метод 'build()'. Это в конечном итоге имеет тот же эффект, что и конструктор копирования. –

+0

Старый объект ссылки означает «старый» объект MsProjectTaskData. Я хочу клонировать этот объект с новым значением, которое устанавливается в методеTransfered (true). – sk2212

+0

В этом специальном случае простую функцию setTransfered() выполнила бы задание. Если ваша цель - познакомиться с шаблоном-строителем и его реализацией, я думаю, вам придется пойти и найти лучший пример. То, что вы здесь делаете, больше похоже на прототипирование для меня. – Fildor

ответ

11

Сделать конструктор Builder в качестве аргумента «старым» объектом и установить все, что вы хотите от него, к новому.

Редактировать

Вы должны прочитать немного больше о шаблоне строитель, чтобы получить лучшее понимание на то, что она есть, и если вы действительно нужно.

Общая идея заключается в том, что шаблон Builder используется, когда у вас есть факультативно элементов. Эффективный 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 
+0

Не могли бы вы предоставить какой-то код? Я не получил его для работы :( – sk2212

+0

@ sk2212 см. Мое редактирование – Eugene

+0

спасибо, что работает! Ну, вы говорите, что, возможно, использование шаблона Builder здесь не очень полезно. В настоящее время я пытаюсь изменить мои изменяемые объекты моего текущего проекта к неизменяемым.Это не так просто, если мне нужно изменить свойство такого объекта и вернуть его обратно в контейнерный arraylist. – sk2212

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

Смежные вопросы