tgoop.com/advice17/6
Last Update:
Говоря про настройки приложений новички зачастую исходят из предположения, что всё приложение - это цельный кусок, который будет один раз настроен до запуска основного кода.
На самом деле это не так:
* Приложение состоит из нескольких независимых частей, которые могут быть переиспользованы
* Некоторые части будут существовать в одном экземпляре, некоторые - нет (по крайней мере в будущем).
* Иногда настройки будут загружаться при старте приложения, иногда - перед созданием конкретных экземпляров классов. Например, при тестировании.
Дополнительно хочу обратить внимание, что зачастую исходный код распространяется в некотором упакованном виде или устанавливается директорию недоступную для изменения и его всё ещё надо настраивать.
Если наше приложение работает в окружении типа k8s, то прокинуть для него файлы может быть затруднительно.
Одновременно вспоминая принципы SOLID можно записать следующие принципы работы с настройками:
1. Настройки приложению должны передаваться как внешние данные: переменные окружения (и иногда файлы).
2. Конкретные "модули" приложения должны зависеть только от своих настроек и не знать о существовании других настроек
3. Настройки "модулей" приложения должны инжектироваться извне, а не читаться неявным образом (путем вызыва функции парсинга настроек или обращения к глобальной переменной)
4. Настройки приложения/"модулей" должны читаться при старте основного кода, а не при импорте
5. Модули не должны знать о том, как именно будут читаться настройки, но могут предоставлять хелперы для этого
Какие есть типичные АНТИПАТТЕРНЫ работы с настройками:
1. Файл settings.py
, содержащий все "константы" настроек, редактируется при деплое. Все куски кода его импортируют.
2. Файл settings.py
, содержащий глобальные переменные, заполненные сразу из переменных окружения.
3. Глобальная переменная, содержащая настройки, все её импортируют. То же самое что п.1, но в какбы-ООП стиле
4. Функция load_config()
, которую все дергают. Для "оптимизации" может быть задекорирована @lru_cache
. По сути то же самое что в п.3, но конфиг читается при первом обращении, которое зачастую происходит в глобальном скоупе и мы это не контролируем.
5. Один класс Settings
и все классы ожидают его целиком, даже если используют лишь часть.
Из наиболее очевидных последствий этих подходов можно выделить сложность тестирования кода, так к моменту запуска тестов настройки уже прочитаны, или необходимость настроить ВСЁ приложение для теста небольшой его части
Иногда фреймворки предлагаю свои подходы для работы с настройками, но это должно использоваться только в тех частях, которые непосредственно связаны с этим фреймворком. В остальные части же настройки должны передаваться как обычно.
BY Советы разработчикам (python и не только)
Share with your friend now:
tgoop.com/advice17/6