Какво е POJO клас?

1. Общ преглед

В този кратък урок ще проучим дефиницията на „Plain Old Java Object“ или 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

Нека добавим зависимостта commons-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 не успя да намери другите две.

Ще видим същия вид резултат, ако използваме други библиотеки като Джаксън за обработка на 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

Когато проверяваме нашия боб с отражение, сега получаваме пълния списък на свойствата:

[firstName, lastName, startDate]

4. Tradeoffs When Using JavaBeans

So, we've shown a way in which JavaBeans are helpful. Keep in mind that every design choice comes with tradeoffs.

When we use JavaBeans we should also be mindful of some potential disadvantages:

  • Mutability – our JavaBeans are mutable due to their setter methods – this could lead to concurrency or consistency issues
  • Boilerplate – we must introduce getters for all properties and setters for most, much of this might be unnecessary
  • Zero-argument Constructor – we often need arguments in our constructors to ensure the object gets instantiated in a valid state, but the JavaBean standard requires us to provide a zero-argument constructor

Given these tradeoffs, frameworks have also adapted to other bean conventions over the years.

5. Conclusion

В този урок сравнихме POJO с JavaBeans.

Първо, научихме, че POJO е Java обект, който не е свързан с конкретна рамка и че JavaBean е специален тип POJO със строг набор от конвенции.

След това видяхме как някои рамки и библиотеки използват конвенцията за именуване JavaBean, за да открият свойствата на класа.

Както обикновено, примерите са достъпни в GitHub.