86 подписчиков
Кстати, хороший пример Data Mapper (в противовес Active Record), в котором персистентность выделена в отдельный слой, чтобы не мешаться с бизнес-логикой. Другой вопрос насколько это хорошо работает (в реальности бывает сложно из-за кучи абстракций)
И в целом все это применимо к MVC. M – тоже требует такого хорошего деления и просто введения сервисов тут не достаточно. Не счесть сколько раз я сталкивался с тем, что любую логику просто пихают в сервисы. Хотя сервисы это в первую очередь Service layer https://martinfowler.com/eaaCatalog/serviceLayer.html
Другой важный принцип проектирования функций Command-Query Separation (CQS). Он не совсем про слои, но очень в тему. Обычно звучит так: "задавая вопрос, не изменяй ответ". То есть геттеры не должны менять состояние, это противоречит их сути и может ломать детерминированность
А команды (любые функции на изменение) не должны возвращать данные. Это создает сложный в понимании код. Хотя справедливости ради, не всегда возможно избавиться от возврата данных у команд. Например открытие соединений или файлов всегда возвращают что-то
Отличный пример того, как рельсы клали на это. Метод .valid? у моделей запускает колбеки типа before_validation(), внутри которых меняют состояние налево и направо. Что приводит к офигеть какому неожиданному коду, когда ты просто проверил валидацию, а у тебя улетел http-запрос
В сети довольно много статей про это https://dan-manges.com/blog/2011/activemodel-validations-and-command-query-separation… Оно касается не только рейлс, похожее есть и в других местах. Рекомендую почитать и задуматься)
1 минута
20 июля 2024