Луковая архитектура
Начал знакомиться с луковой архитектурой, заодно чтобы подкрепить материал решил зарефакторить старый проект.
Создал слой Domain, перекинул все модели из старого проекта в новый, но появилась проблема. В сущности, пусть будет Article(статья), есть метод, который генерирует дату создания статьи
public string GetData(Article model)
{
int createDate = Convert.ToInt32(model.CreateDate.ToString("dd"));
int dateNow = Convert.ToInt32(DateTime.Now.ToString("dd"));
if (createDate == dateNow)
return $"Сегодня, {model.CreateDate.ToString("HH:mm")}";
else if (dateNow - createDate == 1)
return $"Вчера, {model.CreateDate.ToString("HH:mm")}";
else
return $"{model.CreateDate.ToString("dd MMMM, HH:MM")}";
}
Ну и чтобы как-то это выглядело более менее - унаследовал модель от интерфейса и реализовал данный метод. Что , скорее всего, уже неправильно.
Так как слой Domain не может ничего знать про слой Service возникает проблема, ибо интерфейс находится в папке Service.
Как лучше поступить? Понимаю, что можно убрать наследование у модели, тогда не будет ошибки. Но так ведь не грамотно? Да и вообще, правильно ли содержать метод в модели?
Ответы (1 шт):
Шалом!
На самом деле проблема не в самом методе, а в том, что он находится в модели(энтити).
В луковой архитектуре есть несколько типов классов для работы с данными - это
- Entity
- DTO
- ViewModel
Это всё модели, которые хранят данные. Данные передаются из Базы данных в твое представление (WEB View на пример). Модели не содержат в себе методов, которые обрабатывают эти данные. Все манипуляции с данными в модели происходят в Service слое архитектуры проекта. В твоем случае - если надо обработать даты и записать в модель нужные тебе данные - то тебе нужно получить исходные данные из вьюхи или из базы, и обработать их в сервисе.
Собственно есть и архитектурные слои.
- Domain (тут твои Entity)
- Service (Тут DTO)
- Infrastructure (Различные интерфейсы и общие для Service и Presentation классы)
- Presentation (Тут ViewModel)
На пример тебе из вью пришла дата в виде 01-01-2023, тебе надо получить из неё только месяц и записать номер месяца в базу в виде числа. Тебе дата из вью пришла в контроллер, потом ты передаёшь её в сервис, в сервисе из даты берешь месяц, и дальше передаешь в домейн уже месяц в виде числа, записываешь энтити с месяцем в виде числа в БД.
Это работает и в обратную сторону. Если в базе у тебя хранится дата в виде 01-0-2023, а тебе надо в контроллере получить месяц из этой даты в виде числа - то ты в контроллере обращаешься к сервису, сервис обращается к домейну, домейн берет из базы данные, потом возвращает в сервис, сервис из даты берет месяц в виде числа, потом возвращает в контроллер уже число, контроллер передает во вью число месяца.
По сути ты тупо протаскиваешь данные из базы в контроллер и обратно через сервис и попутно в сервисе преобразуешь их как тебе надо. Все модели хранишь в чистом виде, без методов, которые эти данные меняют.
В этом суть луковой архитектуры и суть твоей проблемы - в этой архитектуре есть слои, и каждый слой имеет свою роль. Твоя модель выполняет роль сервиса (она производит изменение данных). Перенеси метод преобразования данных этой модели в сервис, а в модели оставь только поля, и будет тебе красота. Модель в сервис передашь, в сервисе преобразуешь как тебе надо, из контроллера вызовешь этот метод сервиса и получишь то что тебе надо, не нарушая идеи слоёв.