В Effective Java от Joshua Bloch было предложено, что если мы столкнулись со сценарием, в котором у нас много полей в нашем компоненте, мы должны рассмотреть возможность использования компоновщика Builder над телескопическим или java-компонентом. Прочитав пояснительную выдержку из книги, я наткнулся на термин "инвариант". Я думал о многих случаях инвариантов, но не мог подумать о том, что мы не можем заставить пользователя использовать необходимые поля, связанные с инвариантностью, предоставляя им только конструктор такой сигнатуры. Но хорошо ли делать такие вещи? Какую инвариантность мы можем использовать в шаблоне строителя, чтобы гарантировать, что мы используем шаблон, когда мы требуемся, а не только ради него.
не мог действительно думать о том, что мы не можем заставить пользователя использовать необходимые поля, связанные с инвариантностью, предоставляя им только конструктор такой сигнатуры
Это правда. Однако это может быть хорошо, если у вас есть 3, может быть, 4 аргумента. Начиная с 5, ваш конструктор начнет очень долго.
Какую инвариантность мы можем использовать в шаблоне строителя, чтобы гарантировать, что мы используем шаблон, когда мы требуемся, а не только ради него.
Сам строитель не имеет инвариантов; он изменен, не является потокобезопасным. Однако он может генерировать классы с большим количеством инвариантов. Неизменяемые классы, даже; и у них есть много преимуществ (они, например, по сути потокобезопасны).
Еще одно большое преимущество использования построителя заключается в том, что вы можете проверить правильность аргументов в самом построителе и избежать всех этих проверок в конструкторе.
Не говоря уже о том, что если у вас есть несколько конструкторов, вам, вероятно, придется дублировать проверки. С помощью строителя вам нужно будет только сделать эти проверки один раз - в соответствующем .with*()
методе.