Следует ли выполнять вычисления в модели DTO или в модели объекта назначения? - PullRequest
2 голосов
/ 04 мая 2019

В настоящее время я создаю различные сущности в ASP.NET Core 2.2 с сопровождающими DTO для веб-API. Клиентское приложение отправит объект DTO соответствующему действию контроллера. При использовании AutoMapper это будет отображаться из объекта DTO в объект сущности. Полученный объектный объект будет сохранен в репозиторий инфраструктуры объектов, который в данный момент будет базой данных Microsoft SQL. Для краткости предположим, что в этом случае часовые пояса не будут иметь значения.

Мне было просто интересно, какой подход был бы более подходящим или даже не иметь вычисления в DTO или Entity, но, возможно, в действии Controller.

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

Подход № 1

// Entity
public class EventTimes
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public decimal TotalHours => (decimal)(End - Start).TotalHours;
}

// DTO
public class EventTimesDto
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
}

Подход № 2

// Entity
public class EventTimes
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public decimal TotalHours { get; set; }
}

// DTO
public class EventTimesDto
{
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public decimal TotalHours => (decimal)(End - Start).TotalHours;
}

Ответы [ 2 ]

3 голосов
/ 04 мая 2019

Это зависит от фактического контекста.Является ли EventTimes сущностью или это скорее часть вашей доменной модели?

В любом случае я бы не включил ее в dto , поскольку это действительно просто для передачи данных, поэтомуне должно содержать никакой логики (кроме, может быть, проверки).

Поскольку ответственность за этот расчет не является ни частью dto, ни моделью сущностей, вы можете поместить тяжелый расчет в EventTimesCalculator примерно так:

public class EventTimesCalculator
{
    public decimal CalculateTotalHours(EventTimes eventTimes)
    {
        return (decimal)(eventTimes.End - eventTimes.Start).TotalHours;
    }
}

Если EventTimes является частью модели бизнес-уровня / домена, более подходящим способом было бы использование метода GetTotalHours() внутри модели вместо свойства.Конечно, вам необходимо сопоставить его с моделью постоянства, если вы хотите сохранить эту информацию.Опять же, поскольку эта информация может быть рассчитана, вам вообще не нужно ее сохранять, главным образом потому, что логика может измениться (пример: исключить разрывы, прерывания или тому подобное).

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

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

1 голос
/ 04 мая 2019

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

Общий шаблон Объект передачи данных (DTO) - это именно то, что вам нужно для передачи данных между прикладными уровнями, которые могут преобразовывать данные в желаемый вывод. Dto не может содержать бизнес-логику, но также может «подготавливать», «сокращать» данные, которые нужны получателю.

Например:
Если уровню представления требуется totalHours, я делаю это в модели, а не в сущности. Выполнение этого в сущности приведет к бесконечным модификациям.

Другим примером может быть полное имя пользователя Firstname, Lastname, AcademicDegree.

Сущность может содержать их всех, но

  • одна презентация нужна [академическая степень] [имя] [фамилия] и
  • секунды нужны данные в другом формате, например [фамилия] [имя] [ученая степень].


Хорошо сохранить свойство, которое делает желаемый формат в конкретном DTO вместо сущности IMHO.

Я в ASP.NET Core делаю это в луковой архитектуре и вижу модели, и из моего опыта легко управлять, изменять, подготавливать данные для внешнего интерфейса или слоев вместо того, чтобы что-то менять в ядре.

Если кто-то не согласен со мной, пожалуйста, дайте комментарий, мне нравится изучать что-то новое.

Надеюсь, это поможет

...