Лучшим подходом может быть использование Builder, как описано в Effective Java 2nd Edition в пункте 2.
Основная идея состоит в том, чтобы иметь класс Builder, который имеет установщики (нообычно не получатели) для различных параметров конструктора.Также есть метод build()
.Класс Builder часто является (статическим) вложенным классом класса, который используется для построения.Конструктор внешнего класса часто является закрытым.
Конечный результат выглядит примерно так:
public class Foo {
public static class Builder {
public Foo build() {
return new Foo(this);
}
public Builder setId(int id) {
this.id = id;
return this;
}
// you can set defaults for these here
private int id;
}
public static Builder builder() {
return new Builder();
}
private Foo(Builder builder) {
id = builder.id;
}
private final int id;
// The rest of Foo goes here...
}
Чтобы создать экземпляр Foo, вы пишете что-то вроде:
Foo foo = Foo.builder()
.setId(id)
.build();
Вы также можете разделить это, конечно:
// I don't know the ID yet, but I want a place to store it.
Foo.Builder fooBuilder = Foo.builder();
...
// Now I know the ID:.
fooBuilder.setId(id);
...
// Now I'm done and want an immutable Foo.
Foo foo = fooBuilder.build();
У вас может быть несколько сеттеров в компоновщике и даже добавлены дополнительные параметры для build () или конструктора Builder.
ЭтоПозволяет иметь изменяемый объект при разборе, но переключиться на неизменяемый объект, когда вы закончите.Ваш API только когда-либо должен выставлять неизменный объект во многих случаях.