Как обрабатывать и организовывать DTO для разных контекстов? - PullRequest
4 голосов
/ 14 февраля 2010

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

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

  • в дереве, где отображается иерархия, и мне не нужно намного больше, чем отображаемое имя
  • в сетке, где я показываю только пару свойств
  • в области сведений, где имеется большое подмножество доступной информации, но все же некоторая ее часть (например, сопоставленные объекты) отображается только по требованию

Чтобы достичь оптимальной производительности в этом сценарии, я всегда создавал разные DTO для каждого контекста, содержащие только подмножество информации, которая фактически используется в этом контексте. Будучи ресурсосберегающим решением, это приводит к нескольким проблемам:

  • У меня взрыв класса с огромным количеством классов DTO
  • Мне довольно сложно придумывать разные имена для одной и той же вещи, например AssetDtoForGridInTheOverviewScreenInTheUpperPaneAboveTheSplitter, не говоря уже о том, чтобы поддерживать их позже
  • Я часто повторяю себя в методах преобразования, потому что есть свойства, которые используются большинством DTO, но не всеми из них (поэтому я не могу поставить их в любой суперкласс и повторно использовать логику преобразования)

Я использую технологию ASP.NET SOAP WebServices и C # 3.5, но я думаю, что это может быть проблемой, не зависящей от языка. Любые идеи приветствуются ..

Ответы [ 2 ]

3 голосов
/ 14 февраля 2010

Это известная проблема с DTO. Это описано в этом посредственном статье на MSDN . Перефразируя: DTO - это самый универсальный n-уровневый шаблон доступа к данным, но он также требует большей работы.

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

Когда дело доходит до взрыва класса, может быть, вы используете слишком плоские структуры данных?

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

Если, с другой стороны, у вас много повторений на том же уровне приложения (например, пользовательский интерфейс), возможно, вы нарушаете принцип СУХОЙ. В этом случае это может помочь инкапсулировать связанные данные в то, что начинается как плоская структура данных, в отдельный класс. В большинстве известных мне интерфейсов пользовательского интерфейса вы все же можете привязать данные к плоскому дисплею к иерархически структурированному классу.

1 голос
/ 14 февраля 2010

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

С появлением .NET 3.5 вы можете реализовать некоторые базовые, более грубые DTO и заменить ViewModel анонимным типом, который вы можете динамически создавать из DTO. Я обнаружил, что это очень гибкое решение.

Что касается ваших соглашений об именах, вероятно, полезно сгруппировать ваши DTO в сценарии и поместить их в соответствующее пространство имен. Например Solution.AssetManagement.Asset и Solution.AssetReporting.Asset

...