Jak poprawić wzór budowniczy?

Motywacja

Ostatnio szukałem sposobu na zainicjowanie złożonego obiektu bez przekazywania wielu parametrów konstruktorowi. Wypróbowałem go za pomocą wzorca budującego, ale nie podoba mi się fakt, że nie mogę sprawdzić w czasie kompilacji, czy naprawdę ustawiam wszystkie potrzebne wartości.

Tradycyjny wzór budowniczego

Kiedy używam wzoru budowniczego do tworzenia mojegoComplex obiekt, tworzenie jest bardziej „bezpieczne”, ponieważ łatwiej jest zobaczyć, jaki argument jest używany do:

new ComplexBuilder()
        .setFirst( "first" )
        .setSecond( "second" )
        .setThird( "third" )
        ...
        .build();

Ale teraz mam problem, że mogę łatwo przegapić ważny parametr. Mogę to sprawdzić wewnątrzbuild() metoda, ale tylko w czasie wykonywania. W czasie kompilacji nic mnie nie ostrzega, jeśli coś przeoczyłem.

Ulepszony wzór budowniczego

Teraz moim pomysłem było stworzenie budowniczego, który „przypomina” mi, jeśli przegapiłem potrzebny parametr. Moja pierwsza próba wygląda tak:

public class Complex {
    private String m_first;
    private String m_second;
    private String m_third;

    private Complex() {}

    public static class ComplexBuilder {
        private Complex m_complex;

        public ComplexBuilder() {
            m_complex = new Complex();
        }

        public Builder2 setFirst( String first ) {
            m_complex.m_first = first;
            return new Builder2();
        }

        public class Builder2 {
            private Builder2() {}
            Builder3 setSecond( String second ) {
                m_complex.m_second = second;
                return new Builder3();
            }
        }

        public class Builder3 {
            private Builder3() {}
            Builder4 setThird( String third ) {
                m_complex.m_third = third;
                return new Builder4();
            }
        }

        public class Builder4 {
            private Builder4() {}
            Complex build() {
                return m_complex;
            }
        }
    }
}

Jak widać, każdy setter klasy builder zwraca inną wewnętrzną klasę konstruktora. Każda wewnętrzna klasa konstruktora zapewnia dokładnie jedną metodę ustawiającą, a ostatnia dostarcza tylko metodę build ().

Teraz konstrukcja obiektu wygląda tak:

new ComplexBuilder()
    .setFirst( "first" )
    .setSecond( "second" )
    .setThird( "third" )
    .build();

... ale nie ma sposobu, aby zapomnieć o wymaganym parametrze. Kompilator tego nie zaakceptuje.

Opcjonalne parametry

Gdybym miał opcjonalne parametry, użyłbym ostatniej wewnętrznej klasy konstruktoraBuilder4 ustawić je jak „tradycyjnego” budowniczego, powracając sam.

pytaniaCzy to dobrze znany wzór? Czy ma specjalną nazwę?Czy widzisz jakieś pułapki?Czy masz jakieś pomysły na ulepszenie implementacji - w sensie mniejszej liczby linii kodu?

questionAnswers(10)

yourAnswerToTheQuestion