1. Обзор
В этом руководстве мы узнаем, что такое объект передачи данных (DTO), объект значения (VO), обычный старый объект Java (POJO) и JavaBeans. Мы рассмотрим различия между ними и поймем, какой тип использовать и когда.
2. Обычный старый Java-объект
POJO , также известный как Plain Old Java Object, — это обычный объект Java, который не имеет ссылок на какой-либо конкретный фреймворк. Этот термин используется для обозначения простого легковесного объекта Java.
POJO не использует никаких соглашений об именах для свойств и методов.
Давайте определим базовый объект EmployeePOJO
, который имеет три свойства:
public class EmployeePOJO {
private String firstName;
private String lastName;
private LocalDate startDate;
public EmployeePOJO(String firstName, String lastName, LocalDate startDate) {
this.firstName = firstName;
this.lastName = lastName;
this.startDate = startDate;
}
public String name() {
return this.firstName + " " + this.lastName;
}
public LocalDate getStart() {
return this.startDate;
}
}
Как мы видим, приведенный выше объект Java определяет структуру для представления сотрудника и не зависит ни от какой структуры.
3. JavaBeans
3.1. Что такое JavaBean?
JavaBean в основном похож на POJO с некоторым строгим набором правил его реализации.
Правила определяют, что он должен быть сериализуемым, иметь нулевой конструктор и разрешать доступ к переменным с помощью методов, соответствующих соглашениям getX()
и setX()
.
3.2. POJO как JavaBean
Поскольку JavaBean по сути является POJO, давайте преобразуем EmployeePOJO
в JavaBean, реализуя необходимые правила компонента:
public class EmployeeBean implements Serializable {
private static final long serialVersionUID = -3760445487636086034L;
private String firstName;
private String lastName;
private LocalDate startDate;
public EmployeeBean() {
}
public EmployeeBean(String firstName, String lastName, LocalDate startDate) {
this.firstName = firstName;
this.lastName = lastName;
this.startDate = startDate;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
// additional getters and setters
}
Здесь, чтобы преобразовать POJO в JavaBean, мы реализовали интерфейс Serializable , пометили свойства как
private
и использовали методы получения/установки для доступа к свойствам.
4. ДТО
4.1. Шаблон DTO
DTO, также называемый объектом передачи данных , инкапсулирует значения для передачи данных между процессами или сетями.
Это помогает сократить количество вызываемых методов. Включая несколько параметров или значений в один вызов, мы уменьшаем нагрузку на сеть при удаленных операциях.
Еще одним преимуществом этого шаблона является инкапсуляция логики сериализации. Это позволяет программе хранить и передавать данные в определенном формате.
DTO не имеет явного поведения. В основном это помогает сделать код слабо связанным, отделив модели предметной области от уровня представления.
4.2. Как использовать ДТО?
DTO имеют плоскую структуру без какой-либо бизнес-логики. Они используют тот же формат, что и POJO. DTO содержит только хранилище, средства доступа и методы, связанные с сериализацией или синтаксическим анализом.
DTO в основном сопоставляются с моделью предметной области и, таким образом, отправляют данные методу или серверу.
Давайте создадим EmployeeDTO
, который сгруппирует все необходимые данные для создания сотрудника. Мы отправим эти данные на сервер в одном запросе, который оптимизирует взаимодействие с API:
public class EmployeeDTO {
private String firstName;
private String lastName;
private LocalDate startDate;
// standard getters and setters
}
Вышеупомянутый DTO взаимодействует с различными службами и обрабатывает поток данных. Этот шаблон DTO можно использовать в любой службе без ограничений фреймворка.
5. В.О.
VO, также известный как Value Object, представляет собой объект особого типа, который может содержать такие значения, как java.lang.Integer
и java.lang.Long
.
ВО всегда должен переопределять методы equals()
и hashCode() .
ВО обычно инкапсулируют небольшие объекты, такие как числа, даты, строки и т. д. Они следуют семантике значений, т. е. напрямую изменяют значение объекта и передают копии вместо ссылок.
Рекомендуется делать объекты-значения неизменяемыми. Изменение значений происходит только путем создания нового объекта, а не путем обновления значений в самом старом объекте. Это помогает понять неявный контракт, согласно которому два объекта-значения, созданные равными, должны оставаться равными.
Давайте определим EmployeeVO
и переопределим методы equals()
и hashCode() :
public class EmployeeVO {
private String firstName;
private String lastName;
private LocalDate startDate;
public EmployeeVO(String firstName, String lastName, LocalDate startDate) {
this.firstName = firstName;
this.lastName = lastName;
this.startDate = startDate;
}
// Getters
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
EmployeeVO emp = (EmployeeVO) obj;
return Objects.equals(firstName, emp.firstName)
&& Objects.equals(lastName, emp.lastName)
&& Objects.equals(startDate, emp.startDate);
}
@Override
public int hashCode() {
return Objects.hash(firstName, lastName, startDate);
}
}
6. Заключение
В этой статье мы увидели определения POJO, JavaBeans, DTO и Value Objects. Мы также увидели, как некоторые платформы и библиотеки используют соглашения об именах JavaBean и как преобразовать POJO в JavaBean. Мы также рассмотрели шаблон DTO и объекты-значения, а также их использование в различных сценариях.
Как всегда, код этих примеров доступен на GitHub .