"不可变类"的Java构造函数,其中包含许多具有默认值的字段?

zgg*_*ame 21 java oop design-patterns

我有一个包含大量字段的JAVA类.它们基本上应该在构造函数阶段设置,永远不会改变.从语义上讲,类是不可变的.

public class A{
    final int a;
    final short b;
    final double e;
    final String f;
    final String g;
    //and more
}
Run Code Online (Sandbox Code Playgroud)

问题是通常这些字段具有默认值,因此我不希望总是给用户带来包含所有这些字段的构造函数.大多数时候,他们只需要设置几个.有几种方法可以解决这个问题:

  1. 我需要很多具有不同签名的构造函数.
  2. 创建一堆这些字段的set方法,只设置那些非默认值.但这在某种程度上表明了除了不可变性质之外的不同语义.
  3. 创建一个可变的新参数类,并将该类用作构造函数.

这些都不是完全令人满意的.还有其他方法吗?谢谢.单程

Dav*_*rad 27

我将使用参数类和fluent构建器API的组合来创建参数:

public class A {
    private final int a;
    private final short b;
    private final double e;
    private final String g;

    public static class Aparam {
        private int a = 1;
        private short b = 2;
        private double e = 3.141593;
        private String g = "NONE";

        public Aparam a(int a) {
            this.a = a;
            return this;
        }

        public Aparam b(short b) {
            this.b = b;
            return this;
        }

        public Aparam e(double e) {
            this.e = e;
            return this;
        }

        public Aparam g(String g) {
            this.g = g;
            return this;
        }

        public A build() {
            return new A(this);
        }
    }

    public static Aparam a(int a) {
        return new Aparam().a(a);
    }

    public static Aparam b(short b) {
        return new Aparam().b(b);
    }

    public static Aparam e(double e) {
        return new Aparam().e(e);
    }

    public static Aparam g(String g) {
        return new Aparam().g(g);
    }

    public static A build() {
        return new Aparam().build();
    }

    private A(Aparam p) {
        this.a = p.a;
        this.b = p.b;
        this.e = p.e;
        this.g = p.g;
    }

    @Override public String toString() {
        return "{a=" + a + ",b=" + b + ",e=" + e + ",g=" + g + "}";
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样创建A的实例:

A a1 = A.build();
A a2 = A.a(7).e(17.5).build();
A a3 = A.b((short)42).e(2.218282).g("fluent").build();
Run Code Online (Sandbox Code Playgroud)

A类是不可变的,参数是可选的,界面流畅.


Jor*_*dão 19

你可以做两件事: