Подтвердить что ты не робот

В CQRS, должна ли моя сторона чтения возвращать DTO или ViewModels?

У меня есть дебаты с моими коллегами в дизайне стороны чтения приложения CQRS.

Вариант 1:. Среда чтения приложения моего приложения CQRS возвращает DTO, например:

public interface IOrderReadService
{
    public OrderDto Load(int id);
}

public class SomeController
{
    public ActionResult SomeAction(int id)
    {
        var dto = ObjectFactory.GetInstance<IOrderReadService>().Load(id);
        var viewModel = Mapper.Map<OrderDto, SomeViewModel>();
        return View(viewModel);
    }
}

public class SomeOtherController
{
    public ActionResult SomeOtherAction(int id)
    {
        var dto = ObjectFactory.GetInstance<IOrderReadService>().Load(id);
        var viewModel = Mapper.Map<OrderDto, SomeOtherViewModel>();
        return View(viewModel);
    }
}

Вариант 2: Сторона чтения приложения возвращает ViewModels, например:

public interface IOrderReadService
{
    public SomeViewModel LoadSomething(int id);
    public SomeOtherViewModel LoadSomethingElse(int id);
}

public class SomeController
{
    public ActionResult SomeAction(int id)
    {
        return View(ObjectFactory.GetInstance<IOrderReadService>().LoadSomething(id));
    }
}

public class SomeOtherController
{
    public ActionResult SomeOtherAction(int id)
    {
        return View(ObjectFactory.GetInstance<IOrderReadService>().LoadSomethingElse(id));
    }
}

Из исследований, которые мои коллеги и я сделали по этому поводу, ответы кажутся неоднозначными - похоже, что это действительно зависит от контекста. Поэтому я прошу вас, мой дорогой StackOverflowians:

Есть ли у одного подхода очевидные преимущества перед другими? Если да, то каковы они?

4b9b3361

Ответ 1

Общий совет один прогноз на экран (Грег Янг) или даже один прогноз на виджет (если я правильно понимаю Udi Dahan).

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

Мой совет: постарайтесь как можно ближе подобрать SELECT * FROM ViewSpecificTable [WHERE ...] или что-то подобное, если используете NoSQL в вашем тонком слое чтения.

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

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

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

Ответ 2

Одним из основных принципов DDD/CQRS является то, что вы не должны редактировать модель представления. Вместо этого экраны на основе задач должны направлять пользователя к выдаче явных команд. Если вы не можете придумать экраны на основе задач, вы должны использовать другую форму CQRS, такую ​​как описанная здесь:

http://udidahan.com/2011/10/02/why-you-should-be-using-cqrs-almost-everywhere/

Ответ 3

Я бы предпочел вернуть DTO для разделения уровня приложения из технологии представления (поскольку каждая технология представления может иметь некоторые требования к структуре модели представления), например, привязка приложения к веб-MVC отличается от привязки WPF MVVM, также вы можете требуют некоторых свойств/полей в моделях, которые не имеют ничего общего с данными приложения, например, например (SliderWidth или IsEmailFieldEnabled,...). Также, например, при использовании WPF MVVM мне потребуется реализовать интерфейс INotifyPropertyChanged, чтобы разрешить привязку, это не удобно и не связано с реализацией этого интерфейса в службе чтения приложений.

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

Итак, вариант 1 лучше для меня

Ответ 4

Модель чтения - это проекция модели записи. Это там, чтобы выполнить конкретную цель. В вашем случае, который, кажется, предоставляет модели просмотра вашим контроллерам MVC. Как таковые, зачем идти навстречу картированию DTO в Viewmodels? Единственная причина, по которой я мог думать, заключалась в том, что преимущество наличия двух отдельных моделей чтения может не перевесить их расходы на обслуживание. Но подумайте, что "слияние" прочитанных моделей с целью "повторного использования" и "снижения затрат на обслуживание" увеличивает сложность для разработчика (могу ли я изменить эту таблицу? Хм, у меня теперь есть два (или более) потребителя, которых я должен принять Учетная запись - немного напоминает запатентованную интеграцию с базой данных).

Только мои мысли.