что такое dao и dto

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.

Заключение

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

Источник

Забудьте о DAO, используйте Repository

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

Data Access Object (DAO) — широко распространенный паттерн для сохранения объектов бизнес-области в базе данных. В самом широком смысле, DAO — это класс, содержащий CRUD методы для конкретной сущности.
Предположим, что у нас имеется сущность Account, представленная следующим классом:

Создадим интерфейс DAO для данной сущности:

Паттерн Repository

Лучшим решением будет использование паттерна Repository. Эрик Эванс дал точное описание в своей книге: «Repository представляет собой все объекты определенного типа в виде концептуального множества. Его поведение похоже на поведение коллекции, за исключением более развитых возможностей для построения запросов».
Вернемся назад и спроектируем AccountRepository в соответствии с данным определением:

Читайте также:  оформление тортов на день рождения девочке тортов 11 лет

Методы add и update выглядят идентично методам AccountDAO. Метод remove отличается от метода удаления, определенного в DAO тем, что принимает Account в качестве параметра вместо userName (идентификатора аккаунта). Представление репозитория как коллекции меняет его восприятие. Вы избегаете раскрытия типа идентификатора аккаунта репозиторию. Это сделает вашу жизнь легче в том случае, если вы захотите использовать long для идентрификации аккаунтов.
Если вы задумываетесь о контрактах методов add/remove/update, просто подумайте об абстрации коллекции. Если вы задумаетесь о добавлении еще одного метода update для репозитория, подумайте, имеет ли смысл добавлять еще один метод update для коллекции.
Однако, метод query является особенным. Я бы не ожидал увидеть такой метод в классе коллекции. Что он делает?
Репозиторий отличается от коллекции, если рассматривать возможности для построения запросов. Имея коллекцию объектов в памяти, довольно просто перебрать все ее элементы и найти интересующий нас экземпляр. Репозиторий работает с большим набором объектов, чаще всего, находящихся вне оперативной памяти в момент выполнения запроса. Нецелесообразно загружать все аккаунты в память, если нам необходим один конкретный пользователь. Вместо этого, мы передаем репозиторию критерий, с помощью которого он сможет найти один или несколько объектов. Репозиторий может сгенерировать SQL запрос в том случае, если он использует базу данных в качестве бекэнда, или он может найти необходимый объект перебором, если используется коллекция в памяти.
Одна из часто используемых реализаций критерия — паттерн Specification (далее спецификация). Спецификация — это простой предикат, который принимает объект бизнес-области и возвращает boolean:

Итак, мы можем создавать реализации для каждого способа выполнения запросов к AccountRepository.
Обычная спецификация хорошо работает для репозитория в памяти, но не может быть использована с базой данных из-за неэффективности.
Для AccountRepository, работающего с SQL базой данных, спецификации необходимо реализовать интерфейс SqlSpecification:

Репозиторий, использующий базу данных в качестве бекэнда, может использовать данный интерфейс для получения параметров SQL запроса. Если бы в качестве бекэнда для репозитория использовался Hibernate, мы бы использовали интерфейс HibernateSpecification, который генерирует Criteria.
SQL- и Hibernate-репозитории не используется метод specified. Тем не менее, мы находим наличие реализации данного метода во всех классах преимуществом, т.к. таким образом мы сможем использовать заглушку для AccountRepository в тестовых целях а также в кеширующей реализации репозитория перед тем, как запрос будет направлен непосредственно к бекэнду.
Мы даже можем сделать еще один шаг и использовать композицию Spicification с ConjunctionSpecification и DisjunctionSpecification для выполнения более сложных запросов. Нам кажется, что данный вопрос выходит за рамки статьи. Заинтересованный читатель может найти подробности и примеры в книге Эванса.

Источник

Что такое dao и dto

Описать простыми словами термины, встречающиеся при разработке web-приложений:

из браузера

web (controller, view, ui) layer

service layer

dao (repository) layer

domain (model, entity) layer

Plain Old Java Object, старый добрый Java-объект — это объект, состоящий чаще всего из набора полей, их геттеров/сеттеров и без дополнительной нагрузки в виде:

Extend prespecified classes, as in

Implement prespecified interfaces, as in

Contain prespecified annotations, as in (хотя статья на сайте Спринга допускает наличие аннотаций для POJO-объектов )

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

POJO был представлен в качестве альтернативы для Enterprise JavaBeans (EJB) и других «тяжелых» enterprise-конструкций, которые были популярны в 2000-х годах (об этом можно почитать в статье Сергея Немчинского)

Пример:

Таким образом, основной посыл POJO — упрощение классов-сущностей насколько, насколько это возможно для моделирования предметной области

Резюмируя все вышесказанное, можно сказать, что POJO — этот класс, который ничего не делает и имеет только состояние

не путать с Enterprise JavaBeans

это класс в языке Java, написанный по определённым правилам:

Пример:

«Сущности» — это классы, моделирующие объекты предметной области

По своей структуре они приближены к таблицам базы данных (типы и названия столбцов таблицы == типам и названиям полей в классе, взаимодействующему с конкретной таблицей)

Хранятся в domain слое

Сущности почти всегда изменяемы (мутабельны)

«Объект-значение» ⎼ термин из среды DDD ⎼ это объект без специальных методов, имеющий набор свойств (полей) примитивных типов данных или тоже Value object

Читайте также:  как правильно заполнить новую форму 6 ндфл в 2021 за полугодие

Объекты данного рода проверяются на равенство исходя не из физической одинаковости (одинаковости ссылок на них), а из значений свойств

Примером VO является любой класс, который реализует равенство через равенство содержащихся в нем данных

В отличие от Entity не обладает идентичностью. На практике это означает, что объекты-значения не имеют поля-идентификатора: если два экземпляра одного объекта-значения обладают одинаковым набором атрибутов, то они равны

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

Объект-значение всегда должен принадлежать одной или нескольким сущностям, он не может жить собственной жизнью

Чтобы распознать объект-значение, мысленно замените его на Integer

Объекты-значения не должны иметь собственной таблицы в базе данных

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

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

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

Data Access Object, объект доступа к данным — абстрактный интерфейс к какому-либо типу базы данных или иному механизму хранения

Описание проблемы

Способ доступа к данным бывает разным и зависит от источника данных. Способ доступа к базе данных зависит от типа хранилища (реляционные базы данных, объектно-ориентированные базы данных, однородные или «плоские» файлы и т.д.). Унифицированный API для доступа к этим несовместимым системам отсутствует. А использование конкретного способа доступа создает зависимость между кодом приложения и кодом доступа к данным

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

Для доступа к данным хотелось бы использовать какой-либо универсальный способ (паттерн), позволяющий скрыть процесс их получения

Для решения вышеперечисленной проблемы обычно используют паттерн DAO

Описание паттерна

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

В самом широком смысле, DAO — это класс, содержащий CRUD-методы для конкретной сущности

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

Шаблон DAO используется для связи программы, написанной на Java с реляционными базами данных через интерфейс JDBC

JDBC API позволяет в приложениях использовать SQL-команды, являющиеся стандартным средством доступа к таблицам

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

Паттерн DAO позволяет:

Проблемы DAO

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

Чтобы уйти от этого, предлагается использовать паттерн Repository

«Хранилище» ⎼ паттерн, выполняющий роль коллекции объектов из domain layer в оперативной памяти

Хранилище позволяет добавлять или удалять объекты, как будто мы работаем с обычными коллекциями

Тот факт, что объект из domain layer на самом деле не находятся в хранилище, полностью скрыт от клиентских программ. Для них ⎼ это выглядит, как коллекция в памяти

Данный слой используется в Spring Data JPA

REpresentational State Transfer, передача состояния представления

REST определяет набор операций, которые, например User может выполнять над Meals

Дополнительная информация:

Источник

В чем разница между DAL, DTO и DAO в трехуровневом архитектурном стиле, включая MVC

Недавно я изучал ORM (объектно-реляционное сопоставление) и трехуровневый стиль архитектуры (презентация, бизнес и сохранение данных ). Если я правильно понимаю, я могу разделить уровень сохранения данных на уровень DTO и DAO.

Я хотел бы понять, как следующие части работают вместе в слое сохранения данных.

Вдобавок я узнал, что

Буду рад, если кто-нибудь расскажет мне правду о том, как это работает вместе.

Читайте также:  песенка с днем рождения меня с днем рождения меня

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

2 ответа

Объекты передачи данных. Обычно они используются для передачи данных от контроллера к клиенту (JS). Термин также используется для POCO / POJO теми немногими, которые фактически содержат данные, полученные из базы данных.

Уровень доступа к данным абстрагирует ваши действия с базой данных с помощью DAO / Repository / POCO и т. Д. ORM помогают вам создать DAL, но его также можно реализовать без их использования.

Как указано выше, модели потребляют большую часть вашей бизнес-логики. В N-уровневом приложении, если бизнес-логика полностью разделена с целью повторного использования между приложениями / платформами, то модели в MVC называются анемичными моделями. Если BI не нужно повторно использовать в этом масштабе в вашем приложении, вы можете использовать модель для его удержания. Никакой путаницы, правда?

Буду рад, если кто-нибудь расскажет мне правду о том, как это работает вместе.

Все шаблоны MV * определяют только идею / концепцию; они не определяют реализацию. Паттерны MV * в основном сосредоточены на отделении представления от BI. Просто сконцентрируйся на этом.

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

Вы можете сначала провести различие между шаблоном MVC и трехуровневой архитектурой. Подводить итоги:

3-х уровневая архитектура:

Теперь для вышеупомянутой трехуровневой архитектуры шаблон MVC имеет место на уровне представления (для веб-приложения):

Жизненный цикл типичного HTTP-запроса:

Источник

36 уровень. Ответы на вопросы к собеседованию по теме уровня

MVC — это такой паттерн проектирования приложение, при котором приложение разделяется на три отдельные части: модель (model), представление (view) и контроллер (controller). Модель предоставляет данные и реагируется на команды контроллера, изменяя своё состояние. Представление отвечает за отображение данных модели пользователю, реагируя на изменения модели. А контроллер интерпретирует действия пользователя, оповещая модель о необходимости изменений. Таким образом каждый из компонентов этой схемы слабо связан с другими компонентами, за счёт чего достигается гибкость программы. Чаще всего вся бизнес-логика размещается в модели, хотя иногда она содержится и в контроллере. В первом случае модель называют тонкой, в последнем — толстой.

POJO переводится как «объект Java в старом стиле». Их противопоставляют EJB-объектами. Последние следуют специальной конвенции и обычно жёстко привязаны к какому-то конкретному enterprise-фреймворку (например, у них должен быть публичный конструктор без параметров, должен быть геттеры и сеттеры для полей, они должны быть сериализуемыми и т.д.). POJO — это, соответственно, обычный класс, не наследующий ни от каких специальных классов и не реализующий никаких специальных библиотек. Обычно POJO ничего особенного не делает, и содержит только состояние.

Entity Bean — это бин, цель которого хранить некоторые данные. В логику такого бина встроен механизм сохранения себя и своих полей в базу данных. Такой объект может быть уничтожен, а потом воссоздан из базы заново. Но кроме хранения данных у него нет никакой логики. А бин в свою очередь — это особый класс, которые должен выполнять следующие правила:

Очередь (Queue) — это структура данных, работающая по принципу «Первый вошёл — первый вышел». То есть элементы в очередь добавляются с одного конца, а извлекаются — с другого. Deque — это двусторонняя очередь. В этой очереди элементы можно добавлять как в начало, так и в конец, а также брать элементы тоже можно и из начала, и из конца очереди. Соответственно есть методы, которые позволяю положить элемент (это методы add(e) и offer(e)), и есть методы, позволяющие извлечь элемент из очереди (это такие методы, как remove() и poll()). Кроме того, есть методы, которые позволяют просто получить элемент из очереди без его удаления оттуда (это методы element() и peek()). В интерфейсе Deque дополнительно есть методы для добавления элементов в начало и конец очереди, извлечения элементов из начала или конца, а также получения элементов из начала или конца очереди (без их удаления из очереди).

Среди простых реализаций можно отметить ArrayDeque, LinkedList и PriorityQueue. Также существуют много классов в Concurrent Collections, которые реализуют эти два интерфейса (оба сразу или только один из них).

Источник

Академический образовательный портал