Синглтон (1)
Казалось бы, сложно придумать паттерн хуже, чем синглтон. Но нет: на его примере объясняют, как хорошо иметь единственное подключение к базе данных. Специально проверил в Википедии и образовательных статьях.
Делать подключение синглтоном — это примерно как подвесить больного человека вверх ногами и привязать к шее кирпич, думая, что ему станет легче. То есть двигаться в худшую сторону по градиенту — вектору, когда величина нарастает максимально быстро.
Подключение к базе — и вообще любое сетевое подключение — никогда не должно быть синглтоном, и вот почему.
Если подключение не потокобезопасно, то обращение к нему из разных потоков вызовет “рассинхрон”. Например, поток А отправил сообщение, а поток В прочел ответ. В лучшем случае конечный автомат выкинет ошибку, а в худшем — получим неопределенное поведение.
Если же подключение потокобезопасно, то каждый запрос будет блокировать другие потоки: они будут ждать, пока соединение отпустит. В результате 4, 8 или 16 потоков будут работать как один.
Конечно, если у нас скрипт на PHP для заказа пиццы, можно писать в таком ключе: объявить подключение на старте и ссылаться глобально. Для чего-то посложнее так лучше не делать.
Вместо подключения должен быть пул соединений. Каждый раз из него занимают подключение, работают с ним и кладут обратно. Чтобы гарантировать возврат, процесс займа оборачивают в макрос или контекстный менеджер (with в Питоне, try with resource в Джаве).
Но и пул соединений не должен быть синглтоном! Должна быть система компонентов с зависимостями. Пул — один из компонентов, а другие компоненты зависят от него. Специальный код строит граф зависимостей, включает компоненты в нужном порядке и передает им рабочие зависимости.
Другими словами, функция для работы с базой и очередью задач не должна порождать эти компоненты. Она либо принимает их, либо является компонентом, который инициализируется с ними.
Даже если какая-то сущность глобальна по причине легаси, не следуйте плохим практикам. Передавайте ее обычным аргументом. Быть может, ее получится убрать из глобального скоупа, и не придется рефакторить код.
Это в точности мой случай. У нас пул объектов является глобальным — и все равно я ссылаюсь на него лишь однажды, а затем пробрасываю параметром. Верю, что этот промах получится исправить.
Синглтон — это прекрасно для собеса, но никогда не берите его в проект. Включайте, но не пользуйтесь. Пользуйтесь, но не включайте. Не считая этой мелочи, с ним все хорошо.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter