1. Обзор
В этом коротком руководстве мы исследуем определение «простой старый объект Java» или для краткости POJO.
Мы посмотрим, как POJO сравнивается с JavaBean, и чем может быть полезно превращение наших POJO в JavaBeans.
2. Обычные старые объекты Java
2.1. Что такое POJO ?
Когда мы говорим о POJO, мы описываем простой тип без ссылок на какие-либо конкретные фреймворки. POJO не имеет соглашения об именах для наших свойств и методов.
Давайте создадим базовое POJO сотрудника. У него будет три свойства; имя, фамилия и дата начала:
public class EmployeePojo { public String firstName; public 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, поскольку он не привязан к какой-либо структуре.
Но мы не соблюдаем никаких реальных соглашений о создании, доступе или изменении состояния класса.
Это отсутствие условностей вызывает две проблемы:
Во-первых, это увеличивает время обучения кодировщикам, пытающимся понять, как его использовать.
Во-вторых, это может ограничить способность платформы отдавать предпочтение соглашению перед конфигурацией, понимать, как использовать класс, и расширять его функциональность.
Чтобы изучить этот второй момент, давайте поработаем с EmployeePojo, используя отражение. Таким образом, мы начнем обнаруживать некоторые его ограничения.
2.2. Отражение с помощью POJO
Давайте добавим Викисклада BeanUtils зависимость нашего проекта:
commons-beanutils commons-beanutils 1.9.4
А теперь давайте проверим свойства нашего POJO:
List propertyNames = PropertyUtils.getPropertyDescriptors(EmployeePojo.class).stream() .map(PropertyDescriptor::getDisplayName) .collect(Collectors.toList());
Если бы мы распечатали propertyNames на консоль, мы бы увидели только:
[start]
Здесь мы видим , что только получить начать как свойство класса. PropertyUtils не удалось найти два других.
Мы бы увидели такой же результат, если бы использовали другие библиотеки, такие как Jackson, для обработки EmployeePojo.
В идеале мы бы увидели все наши свойства: firstName , lastName и startDate. И хорошая новость заключается в том, что многие библиотеки Java по умолчанию поддерживают так называемое соглашение об именах JavaBean.
3. JavaBeans
3.1. Что такое JavaBean ?
JavaBean по-прежнему является POJO, но вводит строгий набор правил, касающихся того, как мы его реализуем:
- Уровни доступа - наши свойства являются частными, и мы предоставляем геттеры и сеттеры
- Имена методов - наши геттеры и сеттеры следуют соглашениям getX и setX (в случае логического значения isX может использоваться для геттера)
- Конструктор по умолчанию - должен присутствовать конструктор без аргументов, чтобы экземпляр мог быть создан без предоставления аргументов, например, во время десериализации
- Serializable - реализация интерфейса Serializable позволяет нам сохранять состояние
3.2. EmployeePojo как JavaBean
Итак, попробуем преобразовать 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/setters }
3.3. Отражение с помощью JavaBean
Когда мы проверяем наш bean-компонент с помощью отражения, теперь мы получаем полный список свойств:
[firstName, lastName, startDate]
4. Компромиссы при использовании JavaBeans
Итак, мы показали, как JavaBeans полезны. Имейте в виду, что каждый выбор дизайна сопряжен с компромиссами.
Когда мы используем JavaBeans, мы также должны помнить о некоторых потенциальных недостатках:
- Изменяемость - наши JavaBean-компоненты изменяемы из-за их методов установки - это может привести к проблемам с параллелизмом или согласованностью.
- Boilerplate - мы должны ввести геттеры для всех свойств и сеттеры для большинства, большая часть этого может быть ненужной
- Конструктор без аргументов - нам часто нужны аргументы в наших конструкторах, чтобы гарантировать, что объект будет создан в допустимом состоянии, но стандарт JavaBean требует от нас предоставить конструктор с нулевым аргументом
Учитывая эти компромиссы, структуры также адаптировались к другим соглашениям о компонентах с годами.
5. Заключение
В этом руководстве мы сравнили POJO с JavaBeans.
Во-первых, мы узнали, что POJO - это объект Java, который не привязан к определенной структуре, и что JavaBean - это особый тип POJO со строгим набором соглашений.
Затем мы увидели, как некоторые фреймворки и библиотеки используют соглашение об именах JavaBean для обнаружения свойств класса.
Как обычно, примеры доступны на GitHub.