我们如何使用setter而不是构造函数创建不可变的类对象。因为我想使用它的setter方法。它可以使不可变吗?

时间:2017-11-10 12:25:44

标签: java core

使用外部类中的setter方法创建不可变类。因为我有一个POJO类对象创建可以使用setter方法完成。如何使用setter创建不可变

2 个答案:

答案 0 :(得分:0)

塞特犬是变异者。 https://en.wikipedia.org/wiki/Mutator_method

我想你可能指的是工厂方法? https://www.tutorialspoint.com/design_pattern/factory_pattern.htm

或许你可能会有一些混合物。

那些经验丰富的人会有更好的答案。

答案 1 :(得分:0)

您可以使用Builder模式。在那里你有一个单独的构建器类,每个字段都有一种setter。最终build()最终创建了不可变对象。

public final class Person {

  private final String forename;
  private final String surename;
  private final int age;

  private Person(String forename, String surename, int age) {
    this.forename = forename;
    this.surename = surename;
    this.age = age;
  }

  public String getForename() {
    return forename;
  }

  public String getSurename() {
    return surename;
  }

  public int getAge() {
    return age;
  }

  public static PersonBuilder createBuilder() {
    return new PersonBuilder();
  }

  public static class PersonBuilder {

    private String forename;
    private String surename;
    private int age;

    private PersonBuilder() {

    }

    public PersonBuilder withForename(String forename) {
      this.forename = forename;
      return this;
    }

    public PersonBuilder withSurename(String surename) {
      this.surename = surename;
      return this;
    }

    public PersonBuilder withAge(int age) {
      this.age = age;
      return this;
    }

    public Person build() {
      return new Person(forename, surename, age);
    }
  }

然后,您可以创建一个Person实例,如下所示:

Person person = Person.createBuilder().withSurename("Krueger")
                        .withForename("Freddy").withAge(47).build();

使用建筑师,您将拥有两全其美的优势。 setter(包括流畅的API)和最终的不可变对象的灵活性。

修改

约书亚布洛赫在第15项:“有效Java”一书中的“尽量减少可变性”中说:

  

要使类不可变,请遵循以下五条规则:

     
      
  1. 不提供任何修改对象状态的方法(称为mutators)。

  2.   
  3. 确保无法扩展该类。 [...]

  4.   
  5. 将所有字段设为最终字段。 [...]

  6.   
  7. 将所有字段设为私有。 [...]

  8.   
  9. 确保对任何可变组件的独占访问权限。 [...]

  10.   

为了实现第2点,我将final关键字添加到上述Person类中。

根据这个被广泛接受的不变性定义,具有setter的类本身并不是不可变的,因为它违反了第1点。

如果认为在面试中提出这个问题的意图是看到候选人能够认识到问题本身的差异,以及关于不变性的知识和创建不可变类的实例的各种替代方法有多远(每个构造函数,每个静态工厂方法,每个工厂类,每个构建器模式,...)。