Регулярная рубрика "в интернете кто-то не прав" возвращается. Речь сейчас пойдёт об одноимённой статье на медиуме, которую сначала автор запостил в r/Kotlin и r/androiddev, я повозмущался и прошёл мимо, а вчера Android Weekly в своей рассылке прислали и вот это меня уже триггернуло. Я всё ещё зачем-то считаю AW ценным ресурсом, который откровенную дичь не постит.
Человек пишет простыню текста, в которой описывает задачу так: есть какой-то класс, его экземпляр хотим создавать передавая только нужные параметры. Какие у нас варианты? Ну, говорит, можно конструкторы переопределить. Фигня же получается? Да, много кода писать приходится. Ну вот вам решение этой проблемы - Builder Pattern из GOF, в самом его джавовом проявлении на свете. Это когда вы не конструктор у самого объекта вызываете, а какие-то сеттеры у специального билдера, а потом в конце у билдера вызываете какой-нибудь build()
, который экземпляр и создаёт.
Говорит, что таким образом можно держать сам класс иммутабельным, конструктор можно держать один, а ненужные параметры задавать не нужно, инкапсулировали логику создания экземпляра. Одни плюсы. Ну не считая того, что у нас в все проверки валидности ввода теперь из компайл-тайма в рантайм переехали. И не считая того, что мы перечисление всех полей задублировали 3 раза. 🤡
Автор аппелирует к примерам Notification
, AlertDialog
. Говорит - ну вот же, в андроиде такое есть, какой хороший паттерн! Алло, они на джаве написаны, у них выбора просто нет. Если б мне платили каждый раз, когда я забывал вызвать какой-нибудь метод build
, show
или create
... 💰
А что если я скажу, что можно написать data-класс с дефолтными параметрами и при вызове его конструктора использовать именованные параметры, чтобы указать что именно ты хочешь указать? Удивительно, да? Всю эту простыню удалить и заменить на 5 строчек где ты просто конструктор с дефолтными параметрами вызываешь. Да не, бред какой-то.
До кучи накину ещё очевидные архитектурные замечания. Первое - если у тебя слишком много параметров в структуре, то самое время их декомпозировать по группам. Второе - если ты хочешь создать объект, который заполнен частично, то ты делаешь что-то не так, подумай ещё раз, создай вместо этого отдельные части и собирай из них композицию, когда все части уже будут готовы.
Что я прочитал вообще, господи. Образец вредных советов просто, не делайте так.
Описанному автором подходу, на самом деле, осталось место разве что когда вы DSL какой-то пишите (условный StringBuilder
) или библиотеку (условный OkHttp
), но это уже, можно сказать, другое. Автор не об этом совершенно.