Как улучшить шаблон строителя?

мотивация

Недавно я искал способ инициализации сложного объекта без передачи большого количества параметров конструктору. Я попробовал это с шаблоном компоновщика, но мне не нравится тот факт, что я не могу проверить во время компиляции, действительно ли я установил все необходимые значения.

Традиционный образец строителя

Когда я использую шаблон строителя, чтобы создать свойComplex объект, создание более «безопасное», потому что легче увидеть, для чего используется аргумент:

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

Но сейчас у меня проблема, что я могу легко пропустить важный параметр. Я могу проверить это внутриbuild() метод, но это только во время выполнения. Во время компиляции нет ничего, что предупреждает меня, если я что-то пропустил.

Улучшенный шаблон строителя

Теперь моя идея заключалась в том, чтобы создать конструктор, который «напоминает» мне, если я пропустил необходимый параметр. Моя первая попытка выглядит так:

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;
            }
        }
    }
}

Как видите, каждый установщик класса построителя возвращает свой внутренний класс построителя. Каждый внутренний класс построителя предоставляет ровно один метод установки, а последний предоставляет только метод build ().

Теперь конструкция объекта снова выглядит так:

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

... но нет способа забыть необходимый параметр. Компилятор не примет это.

Необязательные параметры

Если бы у меня были необязательные параметры, я бы использовал последний внутренний класс построителяBuilder4 установить их, как это делает «традиционный» строитель, возвращая себя.

ВопросовЭто хорошо известный шаблон? У него есть специальное имя?Вы видите какие-нибудь подводные камни?У вас есть идеи по улучшению реализации - в смысле меньшего количества строк кода?

Ответы на вопрос(10)

Ваш ответ на вопрос