дто что это значит

DTO vs POCO vs Value Object

Определения DTO, POCO и Value Object

Вначале небольшая ремарка по поводу Value Object. В C# существует похожая концепция, называемая Value Type. Это всего лишь деталь имплементации того, как объекты хранятся в памяти и мы не будем касаться этого. Value Object, о котором пойдет речь, — понятие из среды DDD (Domain-Driven Design).

Ок, давайте начнем. Вы возможно заметили, что такие понятия как DTO, Value Object и POCO часто используются как синонимы. Но действительно ли они означают одно и то же?

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

С другой стороны, Value Object — это полноценный член вашей доменной модели. Он подчиняется тем же правилам, что и сущности (Entities). Единственное отличие между Value Object и Entity в том, что у Value Object-а нет собственной идентичности. Это означает, что два Value Object-а с одинаковыми свойствами могут считаться идентичными, в то время как две сущности отличаются друг от друга даже в случае если их свойства полностью совпадают.

Value Object-ы могут содержать логику и обычно они не используются для передачи информации между приложениями.

POJO был представлен Мартином Фаулером в качестве альтернативы для JavaBeans и других «тяжелых» enterprise-конструкций, которые были популярны в ранних 2000-х.

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

Другой хороший пример анти-POCO подхода — Entity Framework до версии 4.0. Каждый класс, сгенерированный EF, наследовал от EntityObject, что привносило в домен логику, специфичную для EF. Начиная с версии 4, Entity Framework добавил возможность работать с POCO моделью — возможность использовать классы, которые не наследуются от EntityObject.

Таким образом, понятие POCO означает использование настолько простых классов насколько возможно для моделирования предметной области. Это понятие помогает придерживаться принципов YAGNI, KISS и остальных best practices. POCO классы могут содержать логику.

Корреляция между понятиями

Есть ли связи между этими тремя понятиями? В первую очередь, DTO и Value Object отражают разные концепции и не могут использоваться взаимозаменяемо. С другой стороны, POCO — это надмножество для DTO и Value Object:

дто что это значит. Смотреть фото дто что это значит. Смотреть картинку дто что это значит. Картинка про дто что это значит. Фото дто что это значит

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

Вот свойства каждого из них:

дто что это значит. Смотреть фото дто что это значит. Смотреть картинку дто что это значит. Картинка про дто что это значит. Фото дто что это значит

Заметьте, что POCO-класс может и иметь, и не иметь собственной идентичности, т.к. он может быть как Value Object, так и Entity. Также, POCO может содержать, а может и не содержать логику внутри себя. Это зависит от того, является ли POCO DTO.

Заключение

Вышесказанное в статье можно суммировать следующим образом:

Источник

Где, когда, зачем и почему надо применять DTO?

Собственно в вопросе все написано. DTO лишь типизация данных, да бы проще оперировать. Так когда, где, когда, зачем и почему?

Зачем я имею ввиду зачем применять именно в конкретной ситуации. скажем можно ли в конструктор юзера передавать UserDto со всеми параметрами? Или нельзя так? Почему?Методы? Где какие границы, сомневаюсь что во все методы на всех слоях приложения можно применять ДТО. да и вообще сомневаюсь что везде можно и нужно. И еще вопрос, фабрика нужна только для сущностей, агрегатов? Или фабрики так же надо создавать для всего что часто инициализируется в проекте?

1. DTO модели, это всего лишь прослойка между сервисами и их предназначение перенести данные от одного сервиса/слоя к другому. Это всегда чистые POCO модели. Если Вы из одного сервиса сразу будете передавать данные в другой сервис, то у Вас выйдет зависимость от типа данных. Т.е., если в первом сервисе изменится тип отдаваемых данных, то придется менять тип входных данных второго сервиса и возможно что-то даже править в коде.

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

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

2. Фабрика нужна там, где нужен контроль создания объекта. Либо ограничение прав его создания, либо принятие решения создания по условию и.т.д.

Источник

Переосмысление DTO в Java

Привет, Хабр! Представляю вашему вниманию любительский перевод статьи “Rethinking the Java DTO” Стивена Уотермана, где автор рассматривает интересный и нестандартный подход к использованию DTO в Java.

Я провел 12 недель в рамках программы подготовки выпускников Scott Logic, работая с другими выпускниками над внутренним проектом. И был момент, который застопорил меня больше других: структура и стиль написания наших DTO. Это вызывало массу споров и обсуждений на протяжении всего проекта, но в итоге я понял, что мне нравится использовать DTO.

Данный подход не является единственно верным решением, но он довольно интересный и отлично подходит для разработки с использованием современных IDE. Надеюсь, что изначальный шок пройдет и вам он тоже понравится.

Что такое DTO (Data Transfer Object)?

Зачастую, в клиент-серверных приложениях, данные на клиенте (слой представления) и на сервере (слой предметной области) структурируются по-разному. На стороне сервера это дает нам возможность комфортно хранить данные в базе данных или оптимизировать использование данных в угоду производительности, в то же время заниматься “user-friendly” отображением данных на клиенте, и, для серверной части, нужно найти способ как переводить данные из одного формата в другой. Конечно, существуют и другие архитектуры приложений, но мы остановимся на текущей в качестве упрощения. DTO-подобные объекты могут использоваться между любыми двумя слоями представления данных.

дто что это значит. Смотреть фото дто что это значит. Смотреть картинку дто что это значит. Картинка про дто что это значит. Фото дто что это значит

DTO — это так называемый value-object на стороне сервера, который хранит данные, используемые в слое представления. Мы разделим DTO на те, что мы используем при запросе (Request) и на те, что мы возвращаем в качестве ответа сервера (Response). В нашем случае, они автоматически сериализуются и десериализуются фреймворком Spring.

Представим, что у нас есть endpoint и DTO для запроса и ответа:

Что делают хорошие DTO?

Во-первых, очень важно понимать, что вы не обязаны использовать DTO. Это прежде всего паттерн и ваш код может работать отлично и без него.

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

Тем не менее, не все DTO являются хорошими. Хорошие DTO помогают создавать API согласно лучшим практикам и в соответствии с принципам чистого кода.

Они должны позволять разработчикам писать API, которое внутренне согласовано. Описание параметра на одной из конечных точек (endpoint) должно применяться и к параметрам с тем же именем на всех связанных точках. В качестве примера, возьмём вышепредставленный фрагмент кода. Если поле price при запросе определено как “цена с НДС”, то и в ответе определение поля price не должно измениться. Согласованное API предотвращает ошибки, которые могли возникнуть из-за различий между конечными точками, и в то же время облегчает введение новых разработчиков в проект.

DTO должны быть надёжными и сводить к минимуму необходимость в написании шаблонного кода. Если при написании DTO легко допустить ошибку, то вам нужно прилагать дополнительные усилия, чтобы ваше API оставалось согласованным. DTO должны “легко читаться”, ведь даже если у нас есть хорошее описание данных из слоя представления — оно будет бесполезно, если его тяжело найти.

Давайте посмотрим на примеры DTO, а потом определим, соответствуют ли они нашим требованиям.

Покажи нам код!

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

Он частично основывается на реальном коде из нашего проекта для выпускников, переведенный в контекст интернет-магазина. В нём каждый продукт имеет название, розничную и оптовую цену. Для хранения цены мы используем тип данных Double, но в реальных проектах вы должны использовать BigDecimal.

Мы создаем по одному файлу для каждого контроллера, который содержит базовый enum без значений, в нашем случае это ProductDTO. Внутри него, мы разделяем DTO на те, что относятся к запросам (Request) и на те, что относятся к ответу (Response). На каждый endpoint мы создаем по Request DTO и столько Response DTO сколько нам необходимо. В нашем случае у нас два Response DTO, где Public хранит данные для любого пользователя и Private который дополнительно содержит оптовую цену продукта.

Для каждого параметра мы создаем отдельный интерфейс с таким же именем. Каждый интерфейс содержит один-единственный метод — геттер для параметра, который он определяет. Любая валидация осуществляется через метод интерфейса. В нашем примере, аннотация @NotBlank проверяет что название продукта в DTO не содержит пустую строку.

Для каждого поля который входит в DTO мы реализовываем соответствующий интерфейс. В нашем случае аннотация @Value из библиотеки Lombok делает это за нас, автоматически генерируя геттеры.

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

“Это ужасно!”

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

Мы используем слишком много интерфейсов — по одному на каждый параметр! Мы делаем это потому что считаем данные интерфейсы единственным источником описательной информации относительно параметра который он определяет. Далее мы поговорим об этом чуть больше, но поверьте мне, это принесет свои плоды.

Мы не реализовали методы интерфейсов. Да, выглядит немного странно и я хотел бы найти решение получше. Сейчас мы используем автогенерацию геттеров при помощи Lombok для закрытия контракта и это небольшой хак. Выглядело бы лучше, если бы мы могли объявлять поля сразу в интерфейсе, что позволяло бы создавать DTO в одной строчке кода. Однако, в java нет возможности интерфейсам иметь не статические поля. Если вы будете использовать этот подход в других языках, то возможно ваш код будет более лаконичным.

Это (почти) идеально

Давайте вернемся к нашим требованиям к созданию хорошего DTO. Соотвествует ли им наш подход?

Согласованный синтаксис

Мы определенно улучшили согласованность синтаксиса и это главное почему мы могли бы начать использовать данный паттерн. Каждый API параметр теперь имеет свой синтаксис, определенный через интерфейс. Если DTO содержит опечатку в имени параметра или некорректный тип — код просто не скомпилируется и IDE выдаст вам ошибку. Для примера:

К тому же, когда мы используем валидацию на уровне интерфейса, мы исключаем ситуацию, когда один и тот же параметр на одном endpoint проходит валидацию и не проходит её на другом.

Согласованная семантика

Такой стиль написания DTO улучшает понимание кода через наследование документации. Каждый параметр имеет свою семантику которая определена в геттер методах соответствующего ему интерфейса. Пример:

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

дто что это значит. Смотреть фото дто что это значит. Смотреть картинку дто что это значит. Картинка про дто что это значит. Фото дто что это значит

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

Читабельность & Поддерживаемость

Будем честны: в нашем подходе достаточно много шаблонного кода. У нас есть 4 интерфейса, без которых не обойтись, и каждый DTO имеет длинную строку с перечислением интерфейсов. Мы можем вынести интерфейсы в отдельный пакет, что поможет избежать лишних “шумов” в коде c описанием DTO. Но даже после этого, бойлерплейт остается главным недостатком данного подхода, что может оказаться веской причиной для того чтобы использовать другой стиль. Для меня, эти затраты все еще стоят того.

К тому же, мы видим всю структуру наших DTO классов. Посмотрите на код и вы увидите все что вам нужно знать из сигнатуры класса. Каждое поле указано в списке реализованных интерфейсов. Достаточно нажать ctrl + q в IntelliJ и вы увидите список полей.

дто что это значит. Смотреть фото дто что это значит. Смотреть картинку дто что это значит. Картинка про дто что это значит. Фото дто что это значит

В нашем подходе мы пишем валидацию единоразово, т.к. она реализуется через методы интерфейса. Создали новое DTO — получили валидацию в подарок, после реализации интерфейса.

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

В java, мы можем реализовать это используя обобщение:

Вывод

Я не жду, что вы сразу же пойдете переписывать все ваши DTO. Но есть несколько деталей которые вы можете почерпнуть для себя:

Источник

Дто что это значит

Смотреть что такое «ДТО» в других словарях:

ДТО — датчик точной остановки в лифтах ДТО дорожно транспортный отдел транспорт ДТО департамент технического обслуживания техн. ДТО до … Словарь сокращений и аббревиатур

деформационно-термическая обработка(ДТО) — [thermomechanical treatment] совокупупность операций горячей обработки давлением и термической обработки сталей и сплавов, совмещенных в одном непрерывном технологическом цикле, например, в линии стана горячей прокатки. ДТО отличается тем, что… … Энциклопедический словарь по металлургии

ОБРАБОТКА ДЕФОРМАЦИОННО-ТЕРМИЧЕСКАЯ — (ДТО) [thermomechanical treatment] совокупность операций горячей обработки давлением и термической обработки сталей и сплавов, совмещенных в одном непрерывном технологическом цикле, например, в линии стана горячей прокатки. ДТО отличается тем,… … Металлургический словарь

будто — 1. союз. 1) Как, словно. Согнулся, бу/дто старик. Упала, бу/дто косой подкосило. Сидит тихо, бу/дто и нет её. 2) в придат. предл. Выражает сомнение, неуверенность в достоверности сообщаемого; что. Показалось, бу/дто огонёк мелькнул. Уверял, б … Словарь многих выражений

Синегубов, Николай Иванович — Николай Иванович Синегубов Начальник ТУ НКВД СССР старший майор госбезопасности Н. И. Синегубов (1941 год) Дата рождения: 30 декабря 1895 … Википедия

будто — I. союз. 1. Как, словно. Согнулся, б. старик. Упала, б. косой подкосило. Сидит тихо, б. и нет её. 2. (в придат. предл.). Выражает сомнение, неуверенность в достоверности сообщаемого; что. Показалось, б. огонёк мелькнул. Уверял, б. видел его… … Энциклопедический словарь

деформационно-термическая обработка — ДТО Совокупность операций горячей обработки давлением и термической обработки сталей и сплавов, совмещенных в одном непрерывном технологическом цикле, например, в линии стана горячей прокатки. ДТО отличается тем, что повышающаяся в результате… … Справочник технического переводчика

обработка деформационно-термическая — ДТО Совокупность операций горячей обработки давлением и термической обработки сталей и сплавов, совмещенных в одном непрерывном технологическом цикле, например, в линии стана горячей прокатки. ДТО отличается тем, что повышение в результате… … Справочник технического переводчика

Центральное управление военных сообщений — Служба военных сообщений Вооружённых Сил Российской Федерации (СВОСО ВС России) Страна … Википедия

Источник

Чистим пхпшный код с помощью DTO

Это моя первая статья, так что ловить камни приготовился.

Возможно, такой подход в PHP сложился исторически, из-за отсутствия строгой типизации и такого себе ООП. Ведь как по мне, то только с 7 версии можно было более-менее реализовать типизацию+ООП, используя strict_types и type hinting.

Также вызов подобных методов может сопровождаться описанием массива, который мы будем передавать. Или вовсе передается какой-то массив с мусором, а метод просто берет нужные ему ключи. Например, сервис по созданию пользователя:

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

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

Собственно, так и появился мой пакет.

Использование ClassTransformer

С его помощью я автоматически привожу данные к нужному мне классу. Рассмотрим более подробно все также на примере создание пользователя. К нам приходит запрос, и данные из него мы должны отправить в метод. В моем случае на Laravel проекте это выглядит вот так:

В запросе к нам приходит массив параметров: name, phone и email. Пакет просто смотрит есть ли такие параметры у класса, и, если есть, сохраняет значение. В противном случае просто отсеивает их. На входе transform можно передавать не только массив, это может быть другой object, из которого также будут разобраны нужные параметры.

Но наименования аргументов могут отличаться. Тогда, в созданной нами DTO, мы можем спокойно описать свою реализацию приведения:

Существуют объекты гораздо сложнее, с параметрами определенного класса, либо массивом объектов. Что же с ними? Все просто, указываем параметру в PHPDoc путь к классу и все. В случае массива нужно указать, каких именно объектов этот массив:

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

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

Метод сервиса работает с конкретным набором данным

Знаем все параметры, которые есть у объекта

Можно задать типизацию каждому параметру

Вызов метода становится проще, за счет удаления приведения вручную

В IDE работают все подсказки.

Аналоги

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

Roadmap

Реализовать метод afterTransform, который будет вызываться после инициализации DTO. Это позволит более гибко кастомизировать приведение к классу. В данный момент, если входные ключи отличаются от внутренних DTO, нужно самому описывать метод transform. И если у нас из 20 параметров только у одного отличается ключ, нам придется описать приведение всех 20. А с методом afterTransform мы сможем кастомизировать приведение только нужного нам параметра, а все остальные обработает пакет.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *