我正在使用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;
}
}
似乎工作或上面的代码有问题?我可以不经考虑使用这种方法吗?
答案 0 :(得分:14)
使Builder构造函数将“旧”对象作为参数,并将您想要的任何内容设置为新对象。
修改强>
您需要阅读有关构建器模式的更多信息,以便更好地了解构建器模式,以及确实需要它。
一般的想法是,当您拥有可选元素时,将使用Builder模式。有效的Java Item 2是你最好的朋友。
对于您的课程,如果您想从另一个对象构建一个对象并同时使用Builder模式,那么
那怎么样?我将只提供你可以自己弄清第二个的第一个。
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
答案 1 :(得分:-1)
我会把它改成
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();
我冒昧地将布尔值更改为“已转移”,我觉得它更容易理解