我正在尝试创建不可变对象的方法。以下构建器对象
之所以具有吸引力,是因为它们使论点的作用清晰易懂。但是我想
使用编译器来验证是否设置了某些字段,例如Immutable()构造函数调用。 StrictImmutableBuilder提供了这些检查,但是比较吵。是否可以通过LaxImmutableBuilder的形式获得相同的检查?也许使用注释?

public class Immutable {

    public static void main(String[] args) {

        new Immutable("13272873C", 23, false);
        // nice but what where those arguments?

        new LaxImmutableBuilder() {{
            refCode("13272873C");
            age(23);
            subscribed(false);
        }}.build();
        // now I know what each value represents
        // but what if I forgot to set one?

        new StrictImmutableBuilder() {
            public String refCode() { return "13272873C"; }

            public int age() { return 23; }

            public boolean subscribed() { return false; }
        }.build();
        // now I'm forced to set each field, but now
        // we have the extra noise of "return"
        // and also "public" if we want to use
        // this outside the current package

        // is there another way? maybe using annotations?
    }

    private final String refCode;
    private final int age;
    private final boolean subscribed;

    public String getRefCode() {
        return refCode;
    }

    public int getAge() {
        return age;
    }

    public boolean isSubscribed() {
        return subscribed;
    }

    public Immutable(String a, int b, boolean c) {
        this.refCode = a;
        this.age = b;
        this.subscribed = c;
    }

}

abstract class StrictImmutableBuilder {
    public abstract String refCode();

    public abstract int age();

    public abstract boolean subscribed();

    public Immutable build() {
        return new Immutable(refCode(), age(), subscribed());
    }
}

abstract class LaxImmutableBuilder {

    private String refCode;
    private int age;
    private boolean subscribed;

    protected void refCode(String refCode) {
        this.refCode = refCode;
    }

    protected void age(int age) {
        this.age = age;
    }

    protected void subscribed(boolean subscribed) {
        this.subscribed = subscribed;
    }

    public Immutable build() {
        return new Immutable(refCode, age, subscribed);
    }

}

最佳答案

这是我使用的模式:

class YourClass {
  // these are final
  private final int x;
  private final int y;

  private int a;
  private int b;

  // finals are passed into the constructor
  private YourClass(int x, int y) {
    this.x = x;
    this.y = y;
  }

  public static class Builder {
    // int x, int y, int a, int b
    // whatever's final is passed into constructor
    public Builder(int x, int y) {
      this.x = x;
      this.y = y;
    }
    // a and b are optional, so have with() methods for these
    public Builder withA(int a) {
      this.a = a;
      return this;
    }
    public Builder withB(int b) {
      this.b = b;
      return this;
    }
    public YourClass build() {
      YourClass c = new YourClass (x, y);
      c.a = a;
      c.b = b;
      return c;
    }
  }
}

07-24 09:50
查看更多