В чем плюсы и минусы синглтона
Что проверяют
Понимаете ли вы, что синглтон это глобальное состояние, и знаете ли, чем оно особенно опасно на Android. Следом спрашивают, чем object в Kotlin отличается от @Singleton в Hilt и что станет с синглтоном после смерти процесса.
Как отвечать
Плюсы:
- один экземпляр тяжёлого ресурса: база Room,
OkHttpClientс общим пулом соединений и кешем,Retrofit. Создавать их на каждый экран дорого и неправильно; - простота: в Kotlin
objectдаёт потокобезопасную ленивую инициализацию бесплатно, её гарантирует инициализация класса в JVM. В Java для того же нужна holder-идиома,enumили double-checked locking сvolatile.
Минусы:
- тестируемость: обращение к глобальному
objectвшито в код, подменить его фейком трудно, а состояние переживает тест и влияет на следующий; - утечки контекста: синглтон, получивший
Activity, держит её вместе со всей иерархией View. Хранить можно толькоapplicationContext, а LeakCanary такие места находит быстро; - смерть процесса: система убивает процесс в фоне, при возврате восстанавливает последнюю
Activity, а синглтон создаётся заново пустым. Данные, которые жили только в нём, пропадают, отсюда падения на ровном месте. Состояние экрана храните вSavedStateHandle, постоянное в базе или DataStore; - многопроцессные приложения: у каждого процесса из
android:processсвой экземпляр.
Хороший вывод: нужна не глобальная точка доступа, а один экземпляр на время жизни приложения. Это даёт DI: в Hilt класс с @Singleton, установленный в SingletonComponent, создаётся один раз, но внедряется через конструктор и подменяется в тестах через @TestInstallIn.
Где спотыкаются
Используют синглтон как хранилище UI-состояния, например текущего пользователя или корзины. После смерти процесса данных нет, а экран ждёт их.
Путают @Singleton в Hilt с Kotlin object. Первый задаёт область жизни в графе зависимостей, второй по сути глобальная переменная.
Передают в синглтон this из Activity. Это классическая утечка, которую ловят на ревью.