使用Builder Pattern构建对象时,如何修改Java中已经构建的对象?
How to modify the already built object in Java, when the Object is built using Builder Pattern?
我已经构建(使用 Builder
模式)一个具有三个字段 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;
}
}
下面Class我已经构建了我的员工对象,
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"?
仅供参考:我不想在我的 Employee
对象中包含 Setters
。
您想修改一个不可变对象。你看到那里的问题了吗?
要么添加 setter(或任何改变状态的方法),要么接受对象是不可变的。
您当然可以根据旧对象的值创建一个新对象,但那样它就不是同一个对象了。
如果您不想放置 setter(并使 Employee 可变),则不能修改 john 的年龄...除此之外,您可以做的是:
employee = new Employee.Builder()
.age("21")
.gender(employee.getGender())
.name(employee.getName())
.build();
使用写时复制构建另一个(重用现有字段但更改年龄)。
Employee.Builder()
.age(employee.getAge() + 1)
.gender(employee.getGender())
.name(employee.getName())
.build();
记住,这将是另一个对象。
如果您不需要 setter 或 public 非最终字段,则可以向构建器添加一个额外的构造函数,这将导致初始状态与实例匹配,但构建器 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();
啊我也试图用这种方法解决我的问题,具有讽刺意味的是我偶然发现了这个问题。我理解这里的挑战,我们正在尝试修改具有相同构建器设置器的对象,但这样做我们最终会得到一个新对象。
我发现有一个解决方案,所以在大约 5 年后,这是我的答案,哈哈(给那些会在这里结束的人)
首先,不要在内部静态生成器中创建 OuterClass 的重复属性 class。 *在 Builder class 中声明一个 outer class 的实例。这意味着您的 build() 方法将 return 该实例。
此*实例声明是有意的,因为我计划在内部创建它或从外部请求它的内存。
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();
我已经构建(使用 Builder
模式)一个具有三个字段 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;
}
}
下面Class我已经构建了我的员工对象,
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"?
仅供参考:我不想在我的 Employee
对象中包含 Setters
。
您想修改一个不可变对象。你看到那里的问题了吗?
要么添加 setter(或任何改变状态的方法),要么接受对象是不可变的。
您当然可以根据旧对象的值创建一个新对象,但那样它就不是同一个对象了。
如果您不想放置 setter(并使 Employee 可变),则不能修改 john 的年龄...除此之外,您可以做的是:
employee = new Employee.Builder()
.age("21")
.gender(employee.getGender())
.name(employee.getName())
.build();
使用写时复制构建另一个(重用现有字段但更改年龄)。
Employee.Builder()
.age(employee.getAge() + 1)
.gender(employee.getGender())
.name(employee.getName())
.build();
记住,这将是另一个对象。
如果您不需要 setter 或 public 非最终字段,则可以向构建器添加一个额外的构造函数,这将导致初始状态与实例匹配,但构建器 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();
啊我也试图用这种方法解决我的问题,具有讽刺意味的是我偶然发现了这个问题。我理解这里的挑战,我们正在尝试修改具有相同构建器设置器的对象,但这样做我们最终会得到一个新对象。
我发现有一个解决方案,所以在大约 5 年后,这是我的答案,哈哈(给那些会在这里结束的人)
首先,不要在内部静态生成器中创建 OuterClass 的重复属性 class。 *在 Builder class 中声明一个 outer class 的实例。这意味着您的 build() 方法将 return 该实例。
此*实例声明是有意的,因为我计划在内部创建它或从外部请求它的内存。
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();