Я работаю над приложением RCP, я новичок в этом приложении.
Spring bean-компоненты используются для написания бизнес-логики для сохранения / извлечения сущностей.
Но вместо того, чтобы отправлять объекты напрямую клиенту, мы конвертируем их в DTO и заполняем клиента. Сохраняя, мы снова конвертируем DTO в сущность и сохраняем.
В чем выгода этих конверсий? Может кто-нибудь объяснить?
What's the benefit of these conversions?
отделение модели постоянства данных от модели данных (представления), предлагаемой потребителям. Преимущества развязки широко обсуждались в SE. Однако цель DTO - собрать в одном ответе столько информации, сколько необходимо клиентам для сохранения вызовов на сервере. Что делает общение клиент-сервер более гладким.Ответы:
Всякий раз, когда разработчик спрашивает «в чем смысл делать это?», Они на самом деле имеют в виду «я не вижу ни одного варианта использования, когда это дает преимущество». Для этого позвольте мне показать вам несколько примеров.
Все примеры будут основаны на этой простой модели данных:
И вы можете предположить, что приложение использует эти данные различными способами (отчеты, формы, всплывающие окна, ...).
Все приложение уже существует. Все, что я упоминаю, является изменением существующей кодовой базы. Это важно помнить.
Пример 1 - Изменение базовой структуры данных - без DTO
Требования изменились. Возраст человека должен быть динамически извлечен из правительственной базы данных (предположим, основываясь на его имени и фамилии).
Поскольку вам больше не нужно хранить
Age
значение локально, его необходимо удалить изPerson
сущности. Здесь важно понимать, что сущность представляет данные базы данных , и ничего более. Если это не в базе данных, это не в сущности.Когда вы извлекаете возраст из правительственного веб-сервиса, он будет храниться в другом объекте (или int).
Но ваш интерфейс все еще отображает возраст. Все представления были настроены для использования
Person.Age
свойства, которое больше не существует. Проблема представляет собой: все взгляды, которые относятся кAge
человеку, должны быть исправлены .Пример 2 - Изменение базовой структуры данных - с DTO
В старой системе, есть также
PersonDTO
объект с теми же пятью свойствами:Id, FirstName, LastName, Age, CityId
. После получения aPerson
, сервисный уровень преобразует его в aPersonDTO
и затем возвращает его.Но теперь требования изменились. Возраст человека должен быть динамически извлечен из правительственной базы данных (предположим, основываясь на его имени и фамилии).
Поскольку вам больше не нужно хранить
Age
значение локально, его необходимо удалить изPerson
сущности. Здесь важно понимать, что сущность представляет данные базы данных , и ничего более. Если это не в базе данных, это не в сущности.Однако, поскольку у вас есть посредник
PersonDTO
, важно видеть , что этот класс может держать вAge
собственности. Сервисный уровень извлекаетPerson
, преобразует его в aPersonDTO
, затем он также извлекает возраст человека из правительственного веб-сервиса, сохраняет это значениеPersonDTO.Age
и передает этот объект.Важной частью здесь является то, что любой, кто использует уровень обслуживания, не видит разницы между старой и новой системой . Это включает в себя ваш интерфейс. В старой системе он получил полный
PersonDTO
объект. И в новой системе он по-прежнему получает полныйPersonDTO
объект. Представления не должны быть обновлены .Вот что мы имеем в виду, когда используем фразу разделения интересов : есть две разные проблемы (хранение данных в базе данных, представление данных во внешнем интерфейсе), и каждый из них нуждается в различном типе данных. Даже если эти два типа данных сейчас содержат одни и те же данные, это может измениться в будущем.
В данном примере
Age
есть различие между двумя типами данных:Person
(объект базы данных) не нуждаетсяAge
, ноPersonDTO
(тип данных внешнего интерфейса) действительно нуждается в этом.Отделяя задачи (= создавая отдельные типы данных) с самого начала, кодовая база намного более устойчива к изменениям, внесенным в модель данных.
Я мог бы привести вам больше примеров, но принцип всегда будет таким же.
Подвести итоги
Person
)Name
. Но только то, что они имеютName
свойство, не означает, что мы должны заставить их наследовать от общегоEntityWithName
базового класса. РазличныеName
свойства не имеют никакого значимого отношения.Name
будет переименованаTitle
, или человек получит «FirstName
а»LastName
), им придется потратить больше усилий, чтобы отменить наследство, которое вам даже не нужно .Как правило, при рассмотрении разделения проблем думайте об этом следующим образом:
Предположим, что каждая проблема (пользовательский интерфейс, база данных, логика) обрабатывается другим человеком в другом месте. Они могут общаться только по электронной почте.
В хорошо разделенной кодовой базе изменение конкретной задачи должно обрабатываться только одним человеком:
Если бы все эти разработчики использовали одну
Person
и ту же сущность и в нее были внесены незначительные изменения, все должны были бы участвовать в этом процессе.Но используя отдельные классы данных для каждого слоя, эта проблема не так распространена:
PersonDTO
объект, бизнес и пользовательский интерфейс не заботятся о том, что он изменил способ хранения / извлечения данных.Ключевая фраза здесь, так как это не влияет на них . Реализация правильного разделения интересов направлена на то, чтобы минимизировать влияние (и, следовательно, необходимость вовлечения) других сторон.
Конечно, нельзя избежать некоторых серьезных изменений, включая более одного человека, например, когда в базу данных добавляется совершенно новый объект. Но не стоит недооценивать количество незначительных изменений, которые вы должны сделать за время жизни приложения. Основные изменения в численном меньшинстве.
источник