W Javie możesz użyć wzorca budującego z wymaganymi i ponownie przypisywanymi polami?
Jest to związane z następującym pytaniem:
Jestem ciekaw, czy możliwe jest zaimplementowanie konstruktora o następujących właściwościach:
Wymagane są niektóre lub wszystkie parametryŻadna metoda nie otrzymuje wielu parametrów (tj. Nie dostarczono żadnej listy wartości domyślnych do początkowej metody fabryki konstruktora)Wszystkie pola konstruktora można przypisać dowolną liczbę razyKompilator powinien sprawdzić, czy wszystkie parametry zostały ustawioneMożna wymagać, aby parametry były początkowo ustawione w pewnej kolejności, ale po ustawieniu dowolnego parametru, wszystkie następne konstruktory mogą ponownie ustawić ten parametr (tj. Można zmienić przypisanie wartości dowolnego pola konstruktora, którego chcesz)W przypadku setterów nie powinien istnieć duplikat kodu (np. Brak nadpisujących metod ustawiających w podtypach konstruktora)Jedna nieudana próba jest poniżej (pominięto puste prywatne konstruktory). Rozważmy następującą implementację konstruktora zabawek i zauważmy, że wiersz z „Foo f2” zawiera błąd kompilatora, ponieważ dziedziczony setter dla zwraca BuilderB, a nie BuilderFinal. Czy istnieje sposób na użycie systemu typu java w celu sparametryzowania typów powrotu seterów, aby osiągnąć powyższe cele, lub osiągnąć je w inny sposób.
public final class Foo {
public final int a;
public final int b;
public final int c;
private Foo(
int a,
int b,
int c) {
this.a = a;
this.b = b;
this.c = c;
}
public static BuilderA newBuilder() {
return new BuilderC();
}
public static class BuilderA {
private volatile int a;
public BuilderB a(int v) {
a = v;
return (BuilderB) this;
}
public int a() {
return a;
}
}
public static class BuilderB extends BuilderA {
private volatile int b;
public BuilderC b(int v) {
b = v;
return (BuilderC) this;
}
public int b() {
return b;
}
}
public static class BuilderC extends BuilderB {
private volatile int c;
public BuilderFinal c(int v) {
c = v;
return (BuilderFinal) this;
}
public int c() {
return c;
}
}
public static class BuilderFinal extends BuilderC {
public Foo build() {
return new Foo(
a(),
b(),
c());
}
}
public static void main(String[] args) {
Foo f1 = newBuilder().a(1).b(2).c(3).build();
Foo f2 = newBuilder().a(1).b(2).c(3).a(4).build();
}
}