Во время разработки мы часто сталкиваемся с созданием сложных котиков объектов, в которых может быть десяток (а то и два) различных свойств.
Иногда создание котика может выглядеть довольно объемно, а некоторые параметры вообще могут быть опциональными или иметь какие-то значения по умолчанию, но мы всё равно их прописываем каждый раз.
В таких случаях как раз поможет паттерн Builder.
Основная идея: паттерн позволяет пошагово создать сложного котика, указав только нужные параметры. Сам паттерн разделяет создание котика и самого котика. И это позволяет нам менять объект в любой момент, не меняя процесс его создания (вот это звучит просто идеально для всяких публичных библиотек и апи).
Реализация выглядит так:
Посмотреть код можно здесь: https://github.com/Ladgertha/patterns/commit/1a768a2e136e64802afb545a97840219cddc420f
Тут всё просто: у нас есть котик с параметрами. Внутри котика делаем класс Builder и для каждого параметра нужно сделать значение по умолчанию и публичный сеттер. Таким образом, при создании котика мы можем использовать только те сеттеры, которые нам нужны. А остальные значения останутся по умолчанию.
Приватный конструктор у котика позволяет нам гарантировать, что котик может быть создан только через Builder и мы сможем контролировать весь процесс создания. Плюс, теперь в конструктор спокойно сможем добавлять новые параметры и не переживать, что совместимость версий сломается.
Преимущества использования:
- Удобство: паттерн даёт удобный и понятный интерфейс для создания объектов, позволяя нам выбирать и устанавливать нужные свойства.
- Гибкость и расширяемость: мы можем добавлять новые методы в Builder для установки дополнительных свойств без изменения основного кода объекта. Повторюсь, что для публичных библиотек и апи это просто ключевой момент. Никто не любит, когда поднимаешь у библиотеки версию, а всё перестаёт работать, потому что разработчики добавили новый параметр. А так мы можем добавить к котику weight и сделать публичный сеттер со значением по умолчанию.
- Читаемость кода: использование паттерна делает код более читаемым и понятным, поскольку каждый шаг простой и явный.
- Минимализация ошибок: паттерн помогает избежать ошибок при создании объектов, так как мы можем проверять и валидировать свойства на каждом шаге.
Несколько недостатков (я очень старалась их найти):
- Увеличение сложности кода: если у объекта есть большое количество параметров, то придется создать отдельные методы в Builder для каждого параметра. По своему опыту скажу, что иногда такие классы достаточно большие и можно что-то случайно упустить.
- Надо очень внимательно следить за значениями по умолчанию и что они действительно есть, а то котик может создаться некорректно или вообще не создаться.
- Потеря производительности: я знаю, что это очень спорный момент. Я добавила этот пункт, но я не считаю, что он хоть как-то актуален. Говорят, что в редких случаях использование Builder может привести к потере производительности из-за создания дополнительных объектов и вызова дополнительных методов. Однако в большинстве ситуаций эта потеря пренебрежимо мала и не оказывает существенного влияния на производительность приложения.
P.S. Во многих статьях вы ещё встретите упоминание некого Director при построении паттерна Builder. Он нужен, если нам нужно выполнять шаги в определенном порядке. Например, сначала дать имя котику, а потом уже возраст. В этом классе метод, в который передаём сам Builder и внутри котик уже создаётся в том порядке, в котором нужно. Если порядок не важен, то, по моему мнению, этот класс лишний.
Дубль статей в телеграмме — https://t.me/android_junior
Мои заметки в телеграмме — https://t.me/android_junior_notes
P.S. сделано с помощью ChatGPT. :)