Ответ
Singleton считается антипаттерном, потому что он часто вводит глобальное состояние и жесткие зависимости, что нарушает принципы чистого кода и усложняет тестирование.
Основные проблемы:
-
Глобальное состояние:
- Singleton создает точку глобального доступа, делая состояние приложения неявным и труднопредсказуемым.
class AppConfig { static let shared = AppConfig() private init() {} var theme: Theme = .light // Глобальное состояние } // Модификация в любом месте влияет на всю систему AppConfig.shared.theme = .dark
- Singleton создает точку глобального доступа, делая состояние приложения неявным и труднопредсказуемым.
-
Нарушение принципа единой ответственности (SRP):
- Класс-синглтон часто становится "божественным объектом", аккумулирующим несвязанные функции.
-
Сложность тестирования:
- Невозможно изолировать тесты, так как состояние сохраняется между ними. Замена реальной реализации mock-объектом затруднена.
-
Скрытые зависимости:
- Классы, использующие синглтон, имеют скрытую зависимость, не отраженную в их интерфейсе (например, в инициализаторе).
Альтернативы:
- Внедрение зависимостей (Dependency Injection): Явная передача зависимостей через инициализатор или свойство.
- Фабрики или протоколы: Создание абстракций для управления жизненным циклом объектов.
Используйте синглтон только для объектов, которые действительно должны существовать в единственном экземпляре на протяжении всего жизненного цикла приложения (например, абстракция над аппаратным датчиком).
Ответ 18+ 🔞
Да ты послушай, что эти умники про синглтон говорят! Антипаттерн, блядь! Ну да, конечно, антипаттерн, а как же! Сидит такой архитектор, накачанный SOLID'ом, и начинает нести: «Глобальное состояние, блядь! Зависимости скрытые! SRP нарушаем!»
Ну типа смотри, вот тебе классика жанра, Swift, блядь:
class AppConfig {
static let shared = AppConfig()
private init() {}
var theme: Theme = .light // Глобальное состояние
}
// Модификация в любом месте влияет на всю систему
AppConfig.shared.theme = .dark
И что? И всё! Взял и в любом углу своей, сука, трехэтажной архитектуры написал AppConfig.shared.theme = .dark. А потом сиди и гадай, блядь, откуда у тебя в левом нижнем углу экрана тёмная тема, а в правом верхнем — ещё светлая! Волнение ебать! Потому что состояние-то глобальное, его кто угодно и где угодно мог ткнуть. Это ж не явная зависимость, которую в инит запихнули, это — хитрая жопа, которая тебе в самый неожиданный момент вылезет.
А ещё тестирование! Ну расскажи мне, как ты будешь тестировать эту хрень? Один тест поменял shared.theme, а следующий уже получает не пойми что! Изолировать? Да хуй там! Это же синглтон, он один на всю твою тестовую среду! Хочешь подменить mock'ом? Придёшься городить огород, протоколы эти, фабрики... Ёперный театр, а не работа!
И самое пиздатое — он начинает обрастать функционалом, как ёлка игрушками! Захотел ты там конфиг хранить — ок. Потом туда же логирование прикрутил. Потом сетевые запросы. А потом смотришь — а это уже не синглтон, а манда с ушами, божественный объект, который знает и умеет всё, но делает это через жопу.
Так что, чувак, вывод простой: доверия к синглтону — ноль ебать. Бери и явно передавай зависимости, через инициализатор, как нормальные люди. Пусть всё видно, как на ладони. Фабрики, протоколы — вот твои инструменты.
А синглтон... Ну его, блядь, оставь для случаев, когда реально один экземпляр на всё приложение и больше никак. Типа абстракции над каким-нибудь железным датчиком, который в телефоне один. Вот тогда — может быть. А так — в рот меня чих-пых, неси dependency injection, и будет тебе счастье.