Вопросы по Clean Architecture?

Если я правильно понял, ядром приложения, разрабатываемого с использованием подхода Clean Architecture, являются сущности (Entities). Сущности являются бизнес объектами приложения и содержат самые общие и высокоуровневые правила. Насколько я понял, в сущностях не совсем правильно указывать вторичные ключи (например, userId) и вообще, сущности не являются моделями для ORM. Получается, что если в сущности есть ссылка на пользователя, мы просто добавляем в нее поле типа User. Никаких Id нету, за исключением Id самой сущности. В связи с этим у меня возникает вопрос, который я постараюсь описать в следующем примере.

Допустим, необходимо разработать приложение - список задач. Есть сущности User (пользователь), Task (задача) и Tag (тег). Каждая задача может содержать набор тегов + каждая задача связана с конкретным пользователем. Теги задачи не должны дублироваться. Получается, что в коде будем иметь что-то подобное:
class Task {
    // ...
    public string Text{ get; private set; }
    public User Creator { get; private set; }
    public IList<Tag> Tags { get; private set; }
    // ...
    public void AddTag(Tag tag) {
        // есть ли у задачи такой тег: если нет - добавляем
    }
}

class Tag {
    // ...
    public string Name { get; private set; }
    // ...
}

В приведенном примере есть проблема: получается, что для проверки того факта, что теги не дублируются, их необходимо выгрузить из БД и произвести маппинг с модели ORM на сущность.

Собственно вопрос: если мы работаем с сущностью, которая содержит коллекцию других сущностей, каким образом выполнять проверку правил в отношении коллекций, при этом не выгружая все данные из БД?
  • Вопрос задан
  • 319 просмотров
Решения вопроса 1
@basrach
Есть два варианта.

Первый заключается в том, чтобы выгружать из БД всю коллекцию тегов. В данном случае такое решение будет вполне оправданным. Поскольку обычно задачи, и вообще что-либо, содержат 3-5 тегов, максимум 7-10, очень редко больше. В таком случае вполне нормально сделать свойство Tags у сущности Task и ожидать, что там будут всегда все теги данной задачи. Т.е. всегда загружать коллекцию тегов для задачи при восстановлении задачи из БД.

Второй заключается в том, чтобы вынести логику в Service. CA и подобные архитектуры диктуют лишь то, что бизнес логика (БЛ) должна быть первична, а все остальное вторично и подстраивается под БЛ. Но они не ограничивают в средствах выражения, т.е. необязательно чтобы вся БЛ была в методах сущностей. Наоборот, внутри сущностей должна быть лишь простая логика, а все что посложнее выносится в Domain Service-ы.
Например, можно создать TaskService, в котором будет метод AddNewTagToTask(Tag tag, Task task). Так как это сервис, то здесь можно иметь зависимость на соответствующий репозиторий, и тогда можно проверить наличие тега с помощью него: if (!taskRepository.TaskHaveTag(tag)) { ... }

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

Но стоит заметить, что если выбран второй подход, то стоит убрать свойство Tags из сущности Task. Так как это будет обманом. Представьте, что вы решили не загружать все теги для задачи, а сделать проверку через сервис. Но в проекте вы работаете не один. Другой же программист увидит что есть поле Tags у задачи и попытается использовать его так, как-будто там там содержатся все теги для задачи. Поэтому чтобы не создавать двусмысленности нужно убрать свойство Tags из Task.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@kttotto
пофиг на чем писать
Хочу пруфлинк, от куда такая инфа, что сущности не могут быть моделями ORM и иметь внешние ключи. Как по мне, то это полный бред, потому что сущностями как раз называют базовые модели предметной области, которые как раз зачастую являются мапингом таблиц из БД, а соответственно имею внешние ключи.

Именно поэтому основная ORM в .net носит название Entity Framework, а ее модели называют сущностями.

Вот определение модели-сущности:

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

Сущность (entity) - это объект, который может быть идентифицирован неким способом, отличающим его от других объектов. Примеры: конкретный человек, предприятие, событие и т.д.

Набор сущностей (entity set) - множество сущностей одного типа (обладающих одинаковыми свойствами). Примеры: все люди, предприятия, праздники и т.д. Наборы сущностей не обязательно должны быть непересекающимися. Например, сущность, принадлежащая к набору МУЖЧИНЫ, также принадлежит набору ЛЮДИ.

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

И напоследок тут.
Ответ написан
ApeCoder
@ApeCoder
В orm моей мечты можно было бы формулировать условия целостности на основном ЯП (типа linq) и они бы транслировались на sql. Не знаю как на реальных orm
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы