tgoop.com/android_live/426
Last Update:
Забытое искусство написания конструкторов
#статьи #разработка
В идеальном мире код разработчика становится лучше день ото дня: то, что мы написали 10 лет назад должно быть лучше того, что мы писали 15 лет назад. Уверен, что в большинстве случаев это именно так.
Сейчас у нас с каждым днём становится всё больше и больше инструментов для разработки, больше «best practises» и современных языков программирования.
Но мы живём в не идеальном мире и часто забываем о некоторых практиках, которых стоит придерживаться. Одна из них — это написание конструкторов.
Конструкторы с большим количеством параметров нарушают принцип единой ответственности: ваш класс делает слишком много одновременно. Максимальное рекомендуемое количество параметров, передаваемое в конструктор — 4. Звучит нереально, учитывая, например, конструкторы Presenter. Автор описывает такой пример:class ProfilePresenter
@Inject
constructor(
@MainThreadScheduler private val mainScheduler: Scheduler,
@IOScheduler private val ioScheduler: Scheduler,
private val profileApi: ProfileApi,
private val userRepository: UserRepository,
private val analytics: Analytics,
private val errorReporter: ErrorReporter
private val referrerTracker: ReferrerTracker,
private val shareTracker: ShareTracker,
private val tracksRepository: TracksRepository,
private val playlistRepository: PlaylistRepository
)
Если бы мы использовали Koin, то код стал бы похож на следующее:ProfilePresenter(get(), get(), get(), get(), get(), get(), get(), get(), get(), get())
Безусловно, это затрудняет понимание инициализации, и тут лучше использовать именование параметров. Но вернёмся к тому, как уменьшить количество параметров.
• выделите общие зависимости
Посмотрев на код, мы можем увидеть общую группу Scheduler
:@MainThreadScheduler private val mainScheduler: Scheduler,
@IOScheduler private val ioScheduler: Scheduler,
Всё это можно объединить одним интерфейсом:interface RxSchedulers {
val io: Scheduler
val computation: Scheduler
val main: Scheduler
}
• используйте фасады
В тех случаях, когда обёртка интерфейсом не помогает, мы можем сделать фасад, спрятав туда похожие классы.
В нашем примере подобными являются классы, ответственные за аналитику:private val analytics: Analytics,
private val referrerTracker: ReferrerTracker,
private val shareTracker: ShareTracker
Попробуем скрыть их в фасад:class ProfileTracker(
private val analytics: Analytics,
private val referrerTracker: ReferrerTracker,
private val shareTracker: ShareTracker
fun trackProfileOpened(referrer: String) =
referrerTracker.profileOpened(referrer)
fun trackProfileShared() =
shareTracker.profileShared()
}
• используйте use case
Ещё одним полезным советом является использование use case. Например, у нас есть несколько репозиториев, ответственных за работу профиля. Мы можем сделать из них один класс:class ProfileUseCase(
private val userRepository: UserRepository,
private val tracksRepository: TracksRepository,
private val playlistRepository: PlaylistRepository,
)
Важно помнить, что количество параметров конструктора — это не серебряная пуля, а только одна из метрик вашего кода. Поэтому, не пытайтесь усложнить ваш код только для того, чтобы уменьшить число параметров. 😎
BY Android Live 🤖

Share with your friend now:
tgoop.com/android_live/426