Перейти к содержимому

Dto java что это

  • автор:

Data Transfer Object (Объект передачи данных)

Fork me on GitHub

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

При работе с удалённым интерфейсом, таким как, например, Remote Facade, каждый запрос к нему достаточно затратен. В результате, приходится уменьшать количество вызовов, что означает необходимость передачи большего количества данных за один вызов. Чтобы реализовать это, как вариант, можно использовать множество параметров. Однако, при этом зачастую код получается неуклюжим и неудобным. Также это часто невозможно в таких языках, как Java, которые возвращают лишь одно значение.

Решением здесь является паттерн Data Transfer Object , который может хранить всю необходимую для вызова информацию. Он должен быть сериализуемым для удобной передачи по сети. Обычно используется объект-сборщик для передачи данных между DTO и объектами в приложении.

В сообществе Sun многие используют термин «Value Object» для обозначения этого паттерна. Мартин Фаулер подразумевает под этим термином ( Value Object ) несколько иной паттерн. Обсуждение этого можно прочесть в его книге P of EEA на странице 487.

Использована иллюстрация с сайта Мартина Фаулера.

  • Главная
  • Список паттернов
  • Сайт создан и поддерживается Василием Кулаковым.

Что такое DTO в Java?

Допустим вы пишите игру шашки. И у вас есть класс Checker. У этого класса будут только поля(цвет, дамка, и т.п.) и геттеры/сеттеры. Вот вам и DTO. Ну и конструктор.

12 дек 2018 в 7:20

Тогда какой смысл в слове Transfer? Он же должен передавать данные по объектам? Как это написано тут DTO

12 дек 2018 в 7:20

@Teemitze DTO переводится как «объект, передающий данные». Данные, которые он передает — это и есть поля.

12 дек 2018 в 7:21

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Объект Customer — DTO.

DTO объект — объект, который не содержит методы. Он может содержать только поля, геттеры/сеттеры, и конструкторы.

Data Transfer Object — объект, передающий данные. Данные — это и есть поля в классе.

Реальный пример — игра шашки. У вас должен быть объект Checker (шашка). У него не должно быть методов, только поля.

public class Checker < private COLOR checkerColor; private Coordinate coordinate; //show checker coordinate private boolean isQueen; //show is the checker queen public Checker(COLOR checkerColor, int xCoordinate, int yCoordinate) < this.checkerColor = checkerColor; coordinate = new Coordinate(xCoordinate, yCoordinate); isQueen = false; >public Checker() <> public COLOR getColor() < return checkerColor; >public Coordinate getCoordinate() < return coordinate; >public boolean isQueen() < return isQueen; >public void setCoordinate(Coordinate coordinate) < this.coordinate.setCoordinates(coordinate.getX(), coordinate.getY()); >public void setQueen() < isQueen = true; >> 

Или класс Cell (шашечное поле).

public class Cell < private boolean isBusy; //shows does the field is occupied with the checker private Coordinate coordinate; //show field coordinate public Cell(boolean isBusy, int x, int y) < coordinate = new Coordinate(x, y); this.isBusy = isBusy; >public Cell() <> public boolean isBusy() < return isBusy; >public void setBusy(boolean isBusy) < this.isBusy = isBusy; >public Coordinate getCoordinate() < return coordinate; >> 

Или класс Board (доска):

public class Board < private Listcells; //list with 64 Fields() private List checkers; //list with Checkers(), whose number falls from 24 to 0 public Board() < cells = new LinkedList<>(); checkers = new LinkedList<>(); > public List getCells() < return cells; >public List getCheckers() < return checkers; >> 

Или класс Coordinate . Хотя у него есть методы(переопределенный equals и compare ), но это методы из Object и он тоже может считаться DTO объектом, т.к. он сделан только для того, что бы хранить данные(координаты).

public class Coordinate < private int x; //x coordinate private int y; //y coordinate public Coordinate(int x, int y) < this.x = x; this.y = y; >public int getX() < return x; >public void setX(int x) < this.x = x; >public int getY() < return y; >public void setY(int y) < this.y = y; >public void setCoordinates(int x, int y) < this.x = x; this.y = y; >@Override public boolean equals(Object o) < if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Coordinate that = (Coordinate) o; return x == that.x && y == that.y; >public boolean compare(Coordinate that, int xMove, int yMove)

Зачем и как использовать Объекты передачи данных в Laravel

Data Transfer Object (Объект передачи данных) — паттерн программирования, который, при правильном использовании, может улучшить качество код и удобство его дальнейшего сопровождения. В этой статье мы узнаем, почему нужно использовать DTO и как это сделать в Laravel.

Что такое объект передачи данных?

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

Зачем использовать DTO

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

Допустим, у меня есть такой код:

class UserController extends Controller < public function store(Request $request): JsonResponse < return response()->json([ $this->service->createUser($request->all()), Response::HTTP_CREATED ]); > >

И мне нужно изменить метод createUser . Это, в целом, довольно простой код, но если бы я его создавал год назад, то и не вспомнил бы какие данные возвращает метод $request->all() .

Я мог бы отрефакторить всё это через класс Custom Request :

class UserController extends Controller < public function store(CreateUserRequest $request): JsonResponse < return response()->json([ $this->service->createUser($request->validated()), Response::HTTP_CREATED ]); > >

Но теперь возникают две другие проблемы:
— валидация теперь связана с HTTP-запросом. Если мне нужно вызвать метод createUser , то мне нужно будет снова вручную провалидировать данные.
— данные маппированы, но поскольку $request->validated() возвращает массив, то не получится принудительно указать тип данных, передаваемых методу createUser .

Если мы применим здесь паттерн DTO, то сможем решить обе вышеописанные проблемы. Будем маппировать и валидировать данные в DTO. И теперь, при вызове метода createUser откуда либо, валидация будет произведена автоматически, нужно просто передать DTO в метод.

Как использовать DTO

Как объяснялось выше, DTO могут быть простыми объектами для маппирования свойств. Таким образом, самой простой реализацией DTO было бы создание следующего класса:

class CreateUserDTO < public function __construct( private string $name, private string $email, private string $username, private string $password ) <>// Add getters, setters, validation >

Затем создаём свой DTO из Request :

class UserController extends Controller < public function store(Request $request): JsonResponse < return response()->json([ $this->service->createUser(new CreateUserDTO(. $request->all())), Response::HTTP_CREATED ]); > >

В new CreateUserDTO(. $request->all()) мы используем именованные аргументы из PHP 8 для создания экземпляра CreateUserDTO .

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

Заключение

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

Если вы хотите начать использовать DTO в своих приложениях, я создал специальный пакет, который предоставляет базовый DTO-класс с валидацией и преобразованием типов, а также artisan-команду для создания DTO.

Наш Телеграм-канал — следите за новостями о Laravel.

Задать вопросы по урокам можно на нашем форуме.

Создание объектов передачи данных (DTO)

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

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

Для этого можно определить объект передачи данных (DTO). DTO — это объект, определяющий способ отправки данных по сети. Давайте посмотрим, как это работает с сущностью Book. В папке Models добавьте два класса DTO:

namespace BookService.Models < public class BookDto < public int Id < get; set; >public string Title < get; set; >public string AuthorName < get; set; >> > namespace BookService.Models < public class BookDetailDto < public int Id < get; set; >public string Title < get; set; >public int Year < get; set; >public decimal Price < get; set; >public string AuthorName < get; set; >public string Genre < get; set; >> > 

Класс BookDetailDto включает все свойства из модели Book, за исключением того, что AuthorName является строкой, которая будет содержать имя автора. Класс BookDto содержит подмножество свойств из BookDetailDto .

Затем замените два метода GET в BooksController классе версиями, возвращающими DTO. Мы будем использовать оператор LINQ Select для преобразования сущностей Book в DTO.

// GET api/Books public IQueryable GetBooks() < var books = from b in db.Books select new BookDto() < Title = b.Title, AuthorName = b.Author.Name >; return books; > // GET api/Books/5 [ResponseType(typeof(BookDetailDto))] public async Task GetBook(int id) < var book = await db.Books.Include(b =>b.Author).Select(b => new BookDetailDto() < Title = b.Title, Year = b.Year, Price = b.Price, AuthorName = b.Author.Name, Genre = b.Genre >).SingleOrDefaultAsync(b => b.Id == id); if (book == null) < return NotFound(); >return Ok(book); > 

Ниже приведен SQL, созданный новым GetBooks методом . Вы видите, что EF преобразует LINQ Select в инструкцию SQL SELECT.

SELECT [Extent1].[Id] AS [Id], [Extent1].[Title] AS [Title], [Extent2].[Name] AS [Name] FROM [dbo].[Books] AS [Extent1] INNER JOIN [dbo].[Authors] AS [Extent2] ON [Extent1].[AuthorId] = [Extent2].[Id] 

Наконец, измените метод , PostBook чтобы он возвращал DTO.

[ResponseType(typeof(BookDto))] public async Task PostBook(Book book) < if (!ModelState.IsValid) < return BadRequest(ModelState); >db.Books.Add(book); await db.SaveChangesAsync(); // New code: // Load author name db.Entry(book).Reference(x => x.Author).Load(); var dto = new BookDto() < Title = book.Title, AuthorName = book.Author.Name >; return CreatedAtRoute("DefaultApi", new < >, dto); > 

В этом руководстве мы преобразуем В DTO вручную в коде. Другой вариант — использовать библиотеку, например AutoMapper , которая обрабатывает преобразование автоматически.

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

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