1概要

この記事では、http://javers.org/documentation/[

JaVers

]ライブラリーを見ていきます。

このライブラリは、プログラマが単純なJavaオブジェクトの状態の変化を調べて検出するのを助けます。コード内で可変オブジェクトを使用すると、アプリケーション内のさまざまな場所ですべてのオブジェクトを変更することができます。


JaVers

は、これらの変更を発見および監査するのに役立ちます


2 Mavenの依存関係

まず始めに、

ja-core

Maven依存関係を

pom.xml

に追加しましょう。

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

最新のバージョンはhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.javers%22%20AND%20a%3A%22javers-core%22[Mavenにあります。中央]。

** 3 POJOの状態変化を検出する+

**

簡単な

Person

クラスから始めましょう。

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

   //standard getters/constructors
}

アプリケーションの一部、およびコードベースの他の部分で

Person

オブジェクトを作成したと仮定します。それらを比較して、人物オブジェクトにどのような変更が行われたのかを調べます。


JaVers

クラスの

compare()

メソッドを使用して、これら2つのオブジェクトを比較できます。

@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オブジェクトリストの状態変化の検出

オブジェクトのコレクションを操作している場合は、同様にコレクション内の各要素を調べて状態の変化を調べる必要があります。

時々、リストに特定のオブジェクトを追加または削除して、その状態を変更したいことがあります。

  • 例を見てみましょう。オブジェクトのリストがあり、そのリストから1つのオブジェクトを削除するとします。

その変更は何らかの理由で望ましくない場合があるので、このリストで発生した変更を監査したいと思います。 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オブジェクトグラフの比較

実際のアプリケーションでは、オブジェクトグラフを扱うことがよくあります。

Address

オブジェクトのリストを持つ

PersonWithAddress

クラスがあり、特定の人物の新しい住所を追加しているとしましょう。

発生した変更の種類を簡単に見つけることができます。

@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. 結論

このクイック記事では、オブジェクトの状態変化を検出するためのAPIを提供する便利なライブラリであるJaVersライブラリを使用しました。単純なPOJOオブジェクトの変更を検出できるだけでなく、オブジェクトのコレクション、またはオブジェクトグラフのより複雑なシフトも検出できます。

いつものように、コードはhttps://github.com/eugenp/tutorials/tree/master/libraries[over GitHub]から入手できます。