Немного размышлений о домене и инфре

от автора

Предположим, вам надо написать десктопное приложение, где будет свое состояние с набором коллекций и других свойств. Объекты для отображения могут храниться древовидно, содержать различные свойства со своей логикой и.т.д. 

Для быстрой реализации этого, надо, как минимум, создать 3 проекта: проект с формочками, проект с доменное логикой, там, где будут манипуляции с объектами: вставкой, удалением и.т.д. И проест с инфраструктурой: работой с бд, файловой системой и.т.д. 

Зависимости проектов будут такими: проекты с формочками и инфрой с бд будут зависеть от проекта с доменными моделями, там, где основное поведение и бизнес логика приложения. 

Формочки используют интерфейсы с методами из доменного проекта, а инфра реализует доменные интерфейса для доступа к данным, работе с фалами и другие взаимодействия, которые не важны в бизнес логике.  

Итого так реализуется основное ядро чистой архитектуры. Но что дальше? 

Дальше встает вопрос: можно ли использовать доменные объекты в представлении? Много кто считает нет. И у этого есть свои обоснования, например, использование атрибутов в моделях представлений.

Но в некоторых случаях, если логика допускает, можно использовать и их, не испытывая никаких лишений. Повторюсь: в некоторых. В любом случае можно всегда создать еще один набор типов для представления, как это всегда делается в web api. 

Теперь перейдем к рассмотрению различных кейсов приложения: управление доменными объектами.  

Предположим, приложение может создавать список, добавлять в список другой список, менять порядок, изменять объект, удалять, вставлять, копировать и.т.д. 

Для каждого действия надо написать логику в доменном проекте и реализовать ее сохранение, например на ef core сущностях. 

При написании таких методов можно заметить, что доменные и методы для работы с ef core местами дублируют логику, но местами имеют очевидные различия. Вставка в коллекцию и выполнение проверок, присваивание свойств и.т.д. 

Вот было бы классно изменять только доменные модели? И не поддерживать два мира с похожим поведение, но разной сутью. 

Я как-то сталкивался с таким совмещением, где ef core модель приколачивается в доменной и живет с ним. С таким подходом есть минусы: зависимость от инфры, либо дополнительная куча абстракций. И сохранение ef core сущности долгое время. Вместо этого поддержка целых «дублирующих» методов для сохранения в бд выглядит на мой взгляд лучше… 

При сохранении надо открыть транзакцию, быстро применить изменения и закрыть транзакцию. При прибивании сущности бд к доменному объекту это так же будет обеспечено. Однако нет гарантии что они будут всегда иметь высокое соответствие, должна быть гибкость. 

Устав плодить и искать несоответствия у двух параллельных миров я наконец-то решился сделать трекер для доменных обетов. О таком я читал в нескольких книгах, и это вполне нормальный unit of work. 

Что надо трекать? Это свойства и коллекции. Как надо трекать? Завести коллекцию с командами. Звучит сложно, но на современном c# это оказалось очень просто и без рефлексий и всяких подписок. 

При изменении свойств добавляем в список делегат, который меняет сущность ef core. При изменении коллекций вычисляем новые элементы и кладем соответствующие делегаты в список изменений. Однако при удалении объекта лучше вызвать трекающий метод отдельно, ну либо подумать, как впихнуть это в домен. Возможно надо подсчитать ссылающихся на объект и удалить если таких уже нет. Однако у меня есть корневые объекты и такое не подходит. 

Итого после доменных изменений надо вызвать один метод трекера, который, по сути, unit of work. В нем создается скоуп зависимостей, и затем выполняются действия на сущностях. Если сущности нет в результате вызова Find(id), то ее можно создать без особых отдельных делегатов создания через Set<T>, но для этого сущности должны быть объединены общим интерфейсом с одним свойством Id. 

В данный момент у меня есть работающая простая реализация, которая, вероятно, будет меняться и пока я её не выложу. Но уже разработка стала гораздо легче. 


ссылка на оригинал статьи https://habr.com/ru/articles/856276/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *