#статьи #разработка
В идеальном мире код разработчика становится лучше день ото дня: то, что мы написали 10 лет назад должно быть лучше того, что мы писали 15 лет назад. Уверен, что в большинстве случаев это именно так.
Сейчас у нас с каждым днём становится всё больше и больше инструментов для разработки, больше «best practises» и современных языков программирования.
Но мы живём в не идеальном мире и часто забываем о некоторых практиках, которых стоит придерживаться. Одна из них — это написание конструкторов.
Конструкторы с большим количеством параметров нарушают принцип единой ответственности: ваш класс делает слишком много одновременно. Максимальное рекомендуемое количество параметров, передаваемое в конструктор — 4. Звучит нереально, учитывая, например, конструкторы Presenter. Автор описывает такой пример:
class ProfilePresenter@Injectconstructor( @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,)Важно помнить, что количество параметров конструктора — это не серебряная пуля, а только одна из метрик вашего кода. Поэтому, не пытайтесь усложнить ваш код только для того, чтобы уменьшить число параметров. 😎