Рубрики
Без рубрики

Когда конструктор является анти-шаблоном

Слепое использование шаблонов считается вредным. С тегами java, lang, beginners.

Некоторое время назад я работал над проектом, который был полон “лучших практик”, тщательно применяемых повсюду. Одной из таких “лучших практик” было обязательное использование Builder для создания POJO’s. Большая часть шаблонного кода POJO была сгенерирована плагином IDE, но это была лишь крошечная часть кода. Реальной проблемой было использование этих POJO. Код был заполнен такими фрагментами, как этот:

    final MyPojo pojo = MyPojo.newBuilder()
                              .setThis(...)
                              .setThat(...)
                              .setSomethingElse(...)
                              ...
                              .build();

Такое чрезмерное использование строителей имеет несколько негативных последствий:

  • код излишне многословен (я бы даже сказал, сильно зашумлен).
  • код подвержен ошибкам

В то время как первая проблема больше зависит от вкуса, вторая – нет: Во время компиляции невозможно определить, установлены ли все необходимые поля.

Простой конструктор all-args или фабричный метод в этом случае работает лучше – компилятор позаботится о том, чтобы я передал все параметры, необходимые для создания POJO. Насколько верны эти параметры, это уже другая история, но все они обязательно будут там. С помощью builder я могу легко опустить один или два. Проблема появится позже, во время выполнения, когда я получу NPE.

Светлый ум, который ввел эту практику в упомянутом выше проекте, решил, что лучший способ решить проблему – добавить проверку в метод build() . Это привело к тому, что вместо того, чтобы получать NPE в случайных местах, мы начали получать их внутри методов build() . Приятное улучшение, не правда ли?

Описанный выше антишаблон является примером более широкого класса серьезных ошибок проектирования – ошибок переноса из времени компиляции во время выполнения. Такой сдвиг влечет за собой проблемы любого масштаба, от более длительной и болезненной разработки до огромных потерь для тех, кто использует приложение.

Итак, как правильно использовать Builder?

Мои критерии правильного использования шаблона Builder чрезвычайно просты: Метод build() должен создать полный экземпляр. Метод

Метод || build() || должен создать || полный || экземпляр. Для всех необходимых полей должны быть установлены разумные значения по умолчанию, если пользователь не предоставил для них значения. POJO редко попадают в категорию классов, которые могут быть построены таким образом. Метод || build() || должен создать || полный || экземпляр. Для всех необходимых полей должны быть установлены разумные значения по умолчанию, если пользователь не предоставил для них значения. POJO редко попадают в категорию классов, которые могут быть построены таким образом. Обычно POJO содержит большинство или все поля, необходимые для представления информации, которая просто не имеет разумных значений по умолчанию.

Метод || build() || должен создать || полный || экземпляр. Для всех необходимых полей должны быть установлены разумные значения по умолчанию, если пользователь не предоставил для них значения. POJO редко попадают в категорию классов, которые могут быть построены таким образом. Обычно POJO содержит большинство или все поля, необходимые для представления информации, которая просто не имеет разумных значений по умолчанию. Еще одно место, где часто используется Builder, – это такие вещи, как конфигурации сервера или клиента, и обычно Builder отлично подходит для такого рода приложений.

Оригинал: “https://dev.to/siy/when-builder-is-anti-pattern-3j92”