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

Введение в JaVers

· 3 мин. чтения

1. Обзор

В этой статье мы рассмотрим библиотеку JaVers .

Эта библиотека помогает программистам исследовать и обнаруживать изменения в состояниях простых объектов Java. Когда мы используем изменяемые объекты в нашем коде, каждый объект потенциально может быть изменен в различных местах приложения; JaVers поможет нам обнаружить и проверить эти изменения .

2. Зависимость от Maven

Для начала давайте добавим зависимость Maven от javers-core в наш pom.xml :

<dependency>
<groupId>org.javers</groupId>
<artifactId>javers-core</artifactId>
<version>3.1.0</version>
</dependency>

Мы можем найти последнюю версию на Maven Central .

3. Обнаружение изменений состояния POJO

Начнем с простого класса Person :

public class Person {
private Integer id;
private String name;

// standard getters/constructors
}

Предположим, что мы создали объект Person в одной части нашего приложения, а в какой-то другой части кодовой базы было изменено имя человека с тем же полем id . Мы хотим сравнить их, чтобы узнать, какие изменения произошли с объектом человека.

Мы можем сравнить эти два объекта, используя метод compare () класса JaVers :

@Test
public void givenPersonObject_whenApplyModificationOnIt_thenShouldDetectChange() {
// given
Javers javers = JaversBuilder.javers().build();

Person person = new Person(1, "Michael Program");
Person personAfterModification = new Person(1, "Michael Java");

// when
Diff diff = javers.compare(person, personAfterModification);

// then
ValueChange change = diff.getChangesByType(ValueChange.class).get(0);

assertThat(diff.getChanges()).hasSize(1);
assertThat(change.getPropertyName()).isEqualTo("name");
assertThat(change.getLeft()).isEqualTo("Michael Program");
assertThat(change.getRight()).isEqualTo("Michael Java");
}

4. Обнаружение изменения состояния списка объектов

Если мы работаем с коллекциями объектов, нам также необходимо исследовать изменения состояния, просматривая каждый элемент в коллекции. Иногда мы хотим добавить или удалить конкретный объект из списка, изменив его состояние.

Давайте посмотрим на пример ; скажем, у нас есть список объектов, и мы удаляем один объект из этого списка.

Это изменение может быть нежелательным по какой-то причине, и мы хотим проверить изменения, произошедшие в этом списке. JaVers позволяет нам сделать это с помощью метода compareCollections() :

@Test
public void givenListOfPersons_whenCompare_ThenShouldDetectChanges() {
// given
Javers javers = JaversBuilder.javers().build();
Person personThatWillBeRemoved = new Person(2, "Thomas Link");
List<Person> oldList =
Lists.asList(new Person(1, "Michael Program"), personThatWillBeRemoved);
List<Person> newList =
Lists.asList(new Person(1, "Michael Not Program"));

// when
Diff diff = javers.compareCollections(oldList, newList, Person.class);

// then
assertThat(diff.getChanges()).hasSize(3);

ValueChange valueChange =
diff.getChangesByType(ValueChange.class).get(0);

assertThat(valueChange.getPropertyName()).isEqualTo("name");
assertThat(valueChange.getLeft()).isEqualTo("Michael Program");
assertThat(valueChange.getRight()).isEqualTo("Michael Not Program");

ObjectRemoved objectRemoved = diff.getChangesByType(ObjectRemoved.class).get(0);
assertThat(
objectRemoved.getAffectedObject().get().equals(personThatWillBeRemoved))
.isTrue();

ListChange listChange = diff.getChangesByType(ListChange.class).get(0);
assertThat(listChange.getValueRemovedChanges().size()).isEqualTo(1);
}

5. Сравнение графиков объектов

В реальных приложениях мы часто имеем дело с графами объектов. Допустим, у нас есть класс PersonWithAddress со списком объектов Address , и мы добавляем новый адрес для данного человека.

Мы можем легко найти тип произошедшего изменения:

@Test
public void givenListOfPerson_whenPersonHasNewAddress_thenDetectThatChange() {
// given
Javers javers = JaversBuilder.javers().build();

PersonWithAddress person =
new PersonWithAddress(1, "Tom", Arrays.asList(new Address("England")));

PersonWithAddress personWithNewAddress =
new PersonWithAddress(1, "Tom",
Arrays.asList(new Address("England"), new Address("USA")));


// when
Diff diff = javers.compare(person, personWithNewAddress);
List objectsByChangeType = diff.getObjectsByChangeType(NewObject.class);

// then
assertThat(objectsByChangeType).hasSize(1);
assertThat(objectsByChangeType.get(0).equals(new Address("USA")));
}

Аналогично будет обнаружено удаление адреса:

@Test
public void givenListOfPerson_whenPersonRemovedAddress_thenDetectThatChange() {
// given
Javers javers = JaversBuilder.javers().build();

PersonWithAddress person =
new PersonWithAddress(1, "Tom", Arrays.asList(new Address("England")));

PersonWithAddress personWithNewAddress =
new PersonWithAddress(1, "Tom", Collections.emptyList());


// when
Diff diff = javers.compare(person, personWithNewAddress);
List objectsByChangeType = diff.getObjectsByChangeType(ObjectRemoved.class);

// then
assertThat(objectsByChangeType).hasSize(1);
assertThat(objectsByChangeType.get(0).equals(new Address("England")));
}

6. Заключение

В этой быстрой статье мы использовали библиотеку JaVers, полезную библиотеку, которая предоставляет нам API для обнаружения изменений состояния наших объектов. Он не только может обнаружить изменение в простом объекте POJO, но также может обнаружить более сложные изменения в коллекциях объектов или даже в графах объектов.

Как всегда, код доступен на GitHub .