我已经构建了(使用Builder
Pattern)一个包含三个字段Name
,Age
和Gender
的Employee对象。
public class Employee {
private String name;
private String age;
private String gender;
// Constructor
private Employee(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.gender = builder.gender;
}
// Employee Builder
public static class Builder {
private String name;
private String age;
private String gender;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(String age) {
this.age = age;
return this;
}
public Builder gender(String gender) {
this.gender = gender;
return this;
}
}
// Getters
public String getName() {
return name;
}
public String getAge() {
return age;
}
public String getGender() {
return gender;
}
}
现在,在以下类中,我构建了我的Employee对象,
public class TestEmployee {
public static void main(String[] args) throws IOException {
Employee employee = new Employee.Builder().age("23").gender("Male").name("John").build();
System.out.println("Name : " + employee.getName());
System.out.println("Age : " + employee.getAge());
System.out.println("Gender : " + employee.getGender());
}
}
如何修改员工的年龄" John"打破已经建立的员工对象?
仅供参考:我不想在Setters
对象中添加Employee
。
答案 0 :(得分:4)
您想要修改不可变对象。你看到那里的问题吗?
添加setter(或任何改变状态的方法)或接受该对象是不可变的。
您当然可以根据旧对象的值创建一个新对象,但它不会是同一个对象。
答案 1 :(得分:2)
使用Copy-On-Write构建另一个(重用现有字段但更改年龄)。
Employee.Builder()
.age(employee.getAge() + 1)
.gender(employee.getGender())
.name(employee.getName())
.build();
请记住,这将是另一个目标。
答案 2 :(得分:2)
啊,我也在尝试用这种方法解决我的问题,具有讽刺意味的是,我偶然发现了这个问题。我了解这里的挑战,我们正在尝试使用相同的构建器设置器修改对象,但这样做最终将得到一个新对象。
我想出了一个解决方案,所以大约5年后,这就是我的回答大声笑(要到这里就结束了)
首先,不要在内部静态Builder类中创建OuterClass的重复属性。 *在Builder类中声明一个外部类的实例。这意味着您的build()方法将返回该实例。
这个实例声明是故意的,因为我打算在内部创建它,或者要从外部请求它的内存。
public class Employee {
private String name;
private String age;
private String gender;
public Static Builder builder()
{
return new Builder();
}
public Static Builder modifier(Employee employee)
{
return new Builder(employee);
}
// Employee Builder
public static class Builder {
private Employee employee;
public Builder(Employee employee)
{
this.employee = employee;
}
public Builder()
{
this.employee = new Employee();
}
public Builder name(String name) {
this.employee.name = name;
return this;
}
public Builder age(String age) {
this.employee.age = age;
return this;
}
public Builder gender(String gender) {
this.gender = gender;
return this;
}
public Employee build()
{
return this.employee;
}
}
// Getters
public String getName() {
return name;
}
public String getAge() {
return age;
}
public String getGender() {
return gender;
}
}
注意这里的调整,我引入了一个带Employee对象的修饰符,并进一步允许客户端使用Builder模式对其进行修改。 因此您的客户将像这样使用它...
创建新员工
Employee employee = Employee.builder().name("abc).age(20).build();
修改同一实例
Employee.modifier(employee)
.name("xyz")
.build();
答案 3 :(得分:1)
如果您不想放置setter(并使Employee变为可变),则无法修改john的年龄...而不是这样,您可以做的是:
employee = new Employee.Builder()
.age("21")
.gender(employee.getGender())
.name(employee.getName())
.build();
答案 4 :(得分:0)
如果您不想要setter或public non-final字段,那么您可以向构建器添加一个额外的构造函数,这将导致初始状态与实例匹配,但可以使用构建器setter。这不会修改原始对象,但会基于它创建一个新对象。
public static class Builder {
private String name;
private String age;
private String gender;
public Builder(Employee employee) {
this.name = employee.getName();
this.age = employee.getAge();
this.gender = employee.getGender();
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(String age) {
this.age = age;
return this;
}
public Builder gender(String gender) {
this.gender = gender;
return this;
}
public Employee build() {
return new Employee(this);
}
}
然后您可以按照以下方式使用它。
Employee employee = new Employee.Builder().age("23").gender("Male").name("John").build();
Employee employee2 = new Employee.Builder(employee).name("Jane").build();