Простой старый объект CLR против объекта передачи данных

POCO = Простой старый объект CLR (или лучше: класс)

DTO = Объект передачи данных

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

POCO и DTO - это одно и то же?

9 ответов

Решение

POCO следует правилам ООП. Он должен (но не должен) иметь состояние и поведение. POCO происходит от POJO, придуманного Мартином Фаулером [ анекдот здесь]. Он использовал термин POJO как способ сделать его более сексуальным, чтобы отвергнуть тяжелые реализации EJB. POCO следует использовать в том же контексте в.Net. Не позволяйте фреймворкам определять дизайн вашего объекта.

Единственная цель DTO - передать состояние и не должна иметь никакого поведения. См. Объяснение DTO Мартина Фаулера для примера использования этого паттерна.

Вот разница: POCO описывает подход к программированию (старомодное объектно-ориентированное программирование), где DTO - это шаблон, который используется для "передачи данных" с использованием объектов.

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

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

Возможно, для меня излишне вносить свой вклад, поскольку я уже изложил свою позицию в своей статье в блоге, но последний абзац этой статьи подводит итог:

Итак, в заключение, научитесь любить POCO и убедитесь, что вы не распространяете никакой дезинформации о том, что это то же самое, что DTO. DTO - это простые контейнеры данных, используемые для перемещения данных между уровнями приложения. POCO - это полноценные бизнес-объекты с одним требованием, чтобы они оставались невосприимчивыми к постоянству (нет методов get или save). И наконец, если вы еще не проверили книгу Джимми Нильссона, возьмите ее из местных стеков университетов. У него есть примеры на C#, и он отлично читается.

Кстати, Патрик Я прочитал POCO как статью о стиле жизни, и я полностью согласен, что это фантастическая статья. На самом деле это раздел из книги Джимми Нильссона, который я рекомендовал. Я понятия не имел, что это было доступно онлайн. Его книга действительно является лучшим источником информации, которую я нашел в POCO / DTO / Repository / и других практиках разработки DDD.

POCO - это просто объект, который не зависит от внешней среды. Это PLAIN.

Неважно, имеет ли POCO поведение или нет.

DTO может быть POCO, как и объект домена (который, как правило, имеет богатое поведение).

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

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

Я написал статью на эту тему: DTO против Value Object против POCO.

Короче:

  • DTO! = Значение объекта
  • DTO ⊂ POCO
  • Объект значения ⊂ POCO

TL;DR:

DTO описывает схему передачи состояния. POCO ничего не описывает. Это еще один способ сказать "объект" в ООП. Оно происходит от POJO (Java), придуманного Мартином Фаулером, который буквально описывает его как более красивое название для "объекта", потому что "объект" не очень привлекателен.

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

POCO - это простой объект, но под "простым" подразумевается то, что он не особенный. Это просто означает, что это объект CLR без подразумеваемого шаблона. Общий термин. Он не предназначен для работы с другими фреймворками. Итак, если ваш POCO имеет[JsonProperty] или украшения EF по всем его свойствам, например, тогда я бы сказал, что это не POCO.

Вот несколько примеров различных паттернов объектов для сравнения:

  • Модель представления: используется для моделирования данных для представления. Обычно имеет аннотации к данным для облегчения привязки и проверки. В MVVM он также действует как контроллер. Это больше, чем DTO
  • Объект значения: используется для представления значений
  • Aggregate Root: используется для управления состоянием и инвариантами
  • Обработчики: используются для ответа на событие / сообщение
  • Атрибуты: используются как украшения для решения сквозных проблем.
  • Сервис: используется для выполнения сложных задач
  • Контроллер: используется для управления потоком запросов и ответов
  • Фабрика: используется для настройки и / или сборки сложных объектов для использования, когда конструктор недостаточно хорош. Также используется для принятия решений о том, какие объекты необходимо создать во время выполнения.
  • Репозиторий /DAO: используется для доступа к данным

Все это просто объекты, но обратите внимание, что большинство из них обычно привязано к узору. Таким образом, вы можете называть их "объектами" или уточнить его намерение и назвать его тем, чем оно является. Вот почему у нас есть шаблоны проектирования; описать сложные концепции в нескольких работах. DTO - это шаблон. Совокупный корень - это шаблон, модель представления - это шаблон (например, MVC и MVVM). POCO - это не шаблон.

POCO не описывает шаблон. Это просто другой способ обращения к классам / объектам в ООП. Думайте об этом как об абстрактном понятии; они могут иметь в виду что угодно. ИМО, существует односторонняя связь, потому что как только объект достигает точки, в которой он может чисто служить только одной цели, он больше не является POCO. Например, как только вы разметите свой класс украшениями, чтобы он работал с какой-либо структурой, он больше не является POCO. Следовательно:

  • DTO - это POCO
  • POCO - это не DTO
  • Модель представления - это POCO
  • POCO - это не модель просмотра

Смысл в том, чтобы проводить различие между ними, состоит в том, чтобы сохранять четкие и последовательные шаблоны, чтобы не перекрестно беспокоиться и не приводить к тесной связи. Например, если у вас есть бизнес-объект, у которого есть методы для изменения состояния, но он также чертовски украшен украшениями EF для сохранения на SQL Server И JsonProperty, чтобы его можно было отправить обратно через конечную точку API. Этот объект будет нетерпимым к изменению и, вероятно, будет завален вариантами свойств (например, UserId, UserPk, UserKey, UserGuid, где некоторые из них помечены, чтобы не сохраняться в БД, а другие помечены, чтобы не сериализоваться в JSON в конечной точке API).

Так что, если бы вы сказали мне, что что-то было DTO, я бы, вероятно, позаботился о том, чтобы оно никогда не использовалось ни для чего, кроме перемещения состояния. Если бы вы сказали мне, что что-то было моделью представления, я бы, вероятно, позаботился о том, чтобы это не сохранялось в базе данных. Если бы вы сказали мне, что что-то было моделью предметной области, я бы, вероятно, удостоверился, что она не имеет зависимости ни от чего за пределами домена. Но если бы вы сказали мне, что что-то было POCO, вы бы вообще не рассказали мне много.

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

Один из примеров, когда POCO отличается от DTO, - это когда вы говорите о POCO внутри модели вашего домена / модели бизнес-логики, которая является хорошим представлением OO вашего проблемного домена. Вы можете использовать POCO во всем приложении, но это может привести к нежелательным побочным эффектам, таким как утечка знаний. DTO, например, используются из сервисного уровня, с которым взаимодействует пользовательский интерфейс, DTO являются плоским представлением данных и используются только для предоставления пользовательскому интерфейсу данных и передачи изменений обратно на сервисный уровень. Уровень обслуживания отвечает за сопоставление обоих направлений DTO с объектами домена POCO.

Мартин Фаулер (Martin Fowler) сказал, что этот подход - трудный путь, и его следует применять только в случае существенного несоответствия между уровнем домена и пользовательским интерфейсом.

Вот общее правило: DTO== зло и индикатор чрезмерно спроектированного программного обеспечения. ПОКО == хорошо. "корпоративные" шаблоны разрушили мозги многих людей в мире Java EE. Пожалуйста, не повторяйте ошибку в.NET Land.

Классы DTO используются для сериализации / десериализации данных из разных источников. Если вы хотите десериализовать объект из источника, не имеет значения, какой это внешний источник: служба, файл, база данных и т. Д., Возможно, вы захотите использовать только некоторую его часть, но вам нужен простой способ десериализации этих данных в объект. после этого вы копируете эти данные в модель XModel, которую хотите использовать. Сериализатор - это красивая технология для загрузки объектов DTO. Зачем? вам нужна только одна функция для загрузки (десериализации) объекта.

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

Даже не называй их DTO. Они называются моделями.... Период. Модели никогда не имеют поведения. Я не знаю, кто придумал этот тупой термин DTO, но это, наверное, вещь.NET - это все, что я могу понять. Подумайте о моделях представления в MVC, то же самое, черт возьми **, модели используются для передачи состояния между слоями на стороне сервера или в течение периода передачи, все они модели. Свойства с данными. Это модели, которые вы передаете по проводу. Модели, Модели Модели. Вот и все.

Я хотел бы, чтобы глупый термин DTO отошел от нашего словаря.

Другие вопросы по тегам