Как избежать избыточной бизнес-логики (выборки БД) при создании DTO?

Я разрабатываю приложение N-уровня на C #. Сторона сервера состоит из следующих слоев:

  • Уровень доступа к данным (EF Code First Entities и DbContext)
  • Бизнес-уровень (содержит всю бизнес-логику и объекты)
  • Уровень службы WCF (службы, созданные для каждого вызова, которые предоставляют некоторые операции из бизнес-уровня)

Теперь запросы клиентов обрабатываются таким образом:

  1. Клиент создает запрос DTO и отправляет его на уровень обслуживания
  2. Уровень сервиса отображает этот DTO на бизнес-объект и вызывает метод BL.
  3. Бизнес-уровень делает что-то полезное, делает запросы к DAL, а затем возвращает некоторый бизнес-объект в службу.
  4. Уровень сервиса сопоставляет бизнес-объект с ответом DTO и возвращает клиенту

Он отлично работает, несмотря на дублирование кода, которое смягчается Automapper. Актуальная проблема заключается в следующем:

Клиент показывает одни и те же объекты в разных представлениях: сетке, форме и т. Д. Например, для представления сетки (списка) требуются только идентификатор и имя из объекта «Пользователь», а для представления «Форма (подробности)» требуется каждое свойство пользователя. Но бизнес-уровень ничего не знает о представлениях. Он может только предоставить полный объект UserBL для вызовов службы, и тогда ответственность за отображение этого UserBL в UserListDto или UserDetailsDto входит в обязанности службы. А для некоторых тяжелых объектов получение дополнительных полей из БД становится проблемой производительности.

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


person v1rusw0rm    schedule 15.12.2015    source источник
comment
Рассматривали ли вы возможность использования кеширования на клиенте? Особенно, если вы снова и снова получаете одну и ту же информацию из уровня сервиса. Насколько изменчивы эти данные?   -  person Darin Dimitrov    schedule 16.12.2015


Ответы (1)


Клиент показывает одни и те же объекты в разных представлениях: сетке, форме и т. Д. Например, для представления сетки (списка) требуются только идентификатор и имя из объекта «Пользователь», а для представления «Форма (подробности)» требуется каждое свойство пользователя. Но бизнес-уровень ничего не знает о представлениях. Он может только предоставить полный объект UserBL для вызовов службы, и тогда ответственность за отображение этого UserBL в UserListDto или UserDetailsDto входит в обязанности службы. А для некоторых тяжелых объектов получение дополнительных полей из БД становится проблемой производительности.

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

По поводу вашей проблемы с дублированием кода. Это не дублирование. У этих разных представлений пользователя разные обязанности.

  • DTO: отвечает за передачу пользователя и создание слабой связи между бизнес-уровнем и потребителем.
  • БО: Ответственный за инкапсуляцию и выполнение бизнес-операций
  • Сущность БД: отвечает за постоянное игнорирование объекта BO

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

person jgauffin    schedule 16.12.2015
comment
Обычно я возвращаю разные представления бизнес-сущности в зависимости от типа действия, совершенного в BL. Думаю, я так и сделаю. В любом случае в BL будет некоторая логика разбиения по страницам \ сортировки, даже если это не чисто доменная логика (или я ошибаюсь?) - person v1rusw0rm; 16.12.2015
comment
По поводу вашей проблемы с дублированием кода. Это не дублирование. У этих разных представлений пользователя разные обязанности. Это именно то, что я думаю, когда делаю разные объекты для разных слоев, даже если эти объекты выглядят очень похоже. Я не объяснил это в вопросе, потому что это немного выходит за рамки вопроса. И я просто упомянул об этом, потому что некоторым разработчикам не нравится, что это нарушает принцип DRY. - person v1rusw0rm; 16.12.2015
comment
Здорово, что ты это тоже знаешь. Как и вы, я встречал нескольких разработчиков, которые хотели использовать один и тот же объект. - person jgauffin; 16.12.2015