почему объекты передачи данных (dto) являются антишаблоном?

<p>недавно я слышал, как люди говорили, что <a href="https://en.wikipedia.org/wiki/data\_transfer\_object">объекты передачи данных</a> (dto) являются <em> антишаблоном </em>.</p><p>зачем? какие есть альтернативы?</p>

<p><strong>некоторые проекты имеют все данные дважды</strong>. один раз как объекты домена и один раз как объекты передачи данных.</p><p>это <strong>дублирование требует огромных затрат</strong>, поэтому архитектура должна получить огромную выгоду от такого разделения, чтобы оно того стоило.</p>

<p>dto не являются антишаблоном. когда вы отправляете некоторые данные по сети (например, на веб-страницу в вызове ajax), вы хотите быть уверены, что вы сохраняете пропускную способность, отправляя только те данные, которые будут использоваться адресатом. кроме того, часто для уровня представления данных удобно иметь данные в несколько ином формате, чем собственный бизнес-объект.</p><p>я знаю, что это вопрос, ориентированный на java, но в языках .net анонимные типы, сериализация и linq позволяют создавать dto "на лету", что сокращает затраты на установку и накладные расходы на их использование.</p>

<p> <a href="http://www.jroller.com/raghukodali/entry/dto\_an\_antipattern\_in\_ejb">dto antipattern в ejb 3.</a> говорит:</p><blockquote> <p>тяжелый вес entity beans в спецификациях ejb до ejb 3.0 привел к использованию шаблонов проектирования, таких как объекты передачи данных (dto). dto стали легковесными объектами (которые должны были быть в первую очередь самими компонентами), используемыми для отправки данных по уровням ... теперь спецификация ejb 3.0 делает модель компонента entity такой же, как plain old java объект (pojo). с этой новой моделью pojo вам больше не нужно будет создавать dto для каждой сущности или для набора сущностей ... если вы хотите отправлять сущности ejb 3.0 по уровню, заставьте их просто реализовать java.io.serialiazable</p> </blockquote>

<p>я не думаю, что dto сами по себе являются анти-паттернами, но есть антипаттерны, связанные с использованием dto. билл дадни ссылается на взрыв dto в качестве примера:</p><p> <a href="http://www.softwaresummit.com/2003/speakers/dudneyj2eeantipatterns.pdf">http://www.softwaresummit.com/2003/speakers/dudneyj2eeantipatterns.pdf</a> </p><p>есть также ряд злоупотреблений dto, упомянутых здесь:</p><p> <a href="http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/">http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/</a> </p><p>они возникли из-за трехуровневых систем (обычно использующих ejb в качестве технологии) в качестве средства передачи данных между уровнями. большинство современных систем java, основанных на таких средах, как spring, используют альтернативное упрощенное представление с использованием pojo в качестве объектов домена (часто аннотируемых с помощью jpa и т.д.) на одном уровне ... использование dto здесь ненужным.</p>

<p>пуристы oo сказали бы, что dto является анти-паттерном, потому что объекты становятся представлениями таблицы данных вместо реальных объектов домена.</p>

<p>некоторые считают dto анти-паттерном из-за их возможных злоупотреблений. они часто используются, когда они не должны быть/не должны быть.</p><p> <a href="http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/">эта статья</a> смутно описывает некоторые злоупотребления.</p>

<p>dto становится необходимостью, а не анти-шаблоном, когда все ваши доменные объекты загружают связанные объекты eagerly.</p><p>если вы не создадите dto, у вас будут ненужные объекты, перенесенные с вашего бизнес-уровня на ваш клиентский/веб-уровень.</p><p>чтобы ограничить накладные расходы в этом случае, лучше перенести dto.</p>

<p>цель <a href="http://martinfowler.com/eaacatalog/datatransferobject.html">data transfer object</a> состоит в том, чтобы сохранить данные из разных источников и затем сразу перенести их в базу данных (или <a href="http://martinfowler.com/eaacatalog/remotefacade.html">remote facade</a> ).</p><p>однако <strong> шаблон dto нарушает <a href="http://www.objectmentor.com/resources/articles/srp.pdf">принцип единой ответственности</a> </strong>, поскольку dto не только хранит данные, но и передает их из или в базу данных/фасад.</p><p>необходимость отделять объекты данных от бизнес-объектов не является антипаттерном, поскольку, вероятно, в любом случае требуется <a href="https://rads.stackoverflow.com/amzn/click/com/0321125215">отделить слой базы данных</a> .</p><p>вместо dto вы должны использовать aggregate и repository patterns, которые разделяют коллекцию объектов ( <a href="http://martinfowler.com/bliki/ddd\_aggregate.html">aggregate</a> ) и передачу данных ( <a href="http://martinfowler.com/eaacatalog/repository.html">repository</a> ).</p><p>для передачи группы объектов вы можете использовать шаблон <a href="http://martinfowler.com/eaacatalog/unitofwork.html">nit of work</a> , который содержит набор репозиториев и контекст транзакции; для передачи каждого объекта в совокупности отдельно в рамках транзакции.</p>

<p>вопрос должен быть не "почему", а "<strong>когда</strong>".</p><p>определенно это <strong>анти-шаблон, когда только результат использования - более высокая стоимость</strong> - время выполнения или обслуживание. я работал над проектами, в которых сотни dto идентичны классам сущностей базы данных. каждый раз, когда вы хотели добавить одно рекламное поле для добавления идентификатора, например, четыре раза - в dto, в сущность, в преобразование из dto в классы или сущности домена, обратное преобразование, ... вы забыли некоторые места и получили данные противоречивы.</p><p>это <strong>не анти-паттерн, когда вам действительно нужно другое представление классов домена</strong> - более плоский, более богатый, более узкий, ...</p><p>лично я начинаю с класса домена и прохожу его с правильной проверкой в нужных местах. я могу аннотировать и/или добавлять некоторые "вспомогательные" классы для создания отображений, базы данных, форматов сериализации, таких как json или xml ... я всегда могу разделить класс на два, если я чувствую необходимость.</p><p>это касается вашей точки зрения - я предпочитаю рассматривать объект домена как отдельный объект, играющий различные роли, а не как несколько объектов, созданных друг от друга. если единственная роль, которую играет объект, - это передача данных, то это dto.</p>

<p>я думаю, что люди подразумевают, что это может быть анти-паттерном, если вы реализуете все удаленные объекты как dto. dto - это просто набор атрибутов, и если у вас есть большие объекты, вы всегда будете передавать все атрибуты, даже если они вам не нужны или не используются. в последнем случае предпочитают использовать шаблон proxy.</p>