Accesseurs avec Lombox

De EjnTricks

L'utilisation de POJO est largement répandue lors de projet JAVA, afin de décrite des objets. Les bonnes pratiques veulent que les fonctions getter et setter soient écrites en respectant une certaine nomenclature.

Or les objets peuvent contenir un grand nombre de variables internes, nécessitant une écriture fastidieuses de ces fonctions. Lombox permet de s'en affranchir à laide des annotations Getter et Setter décrite dans le cadre de cet article.

Le code source est disponible à l'adresse suivante: http://www.jouvinio.net/svn/study/trunk/lombok/, et en particulier les classes du package fr.ejn.tutorial.java.lombok.accessors.


Hand-icon.png Votre avis

Nobody voted on this yet

 You need to enable JavaScript to vote


Vues-icon.png Simple getter / setter

Comme indiquer en présentation, Lombok permet de générer l'ensemble des getter et setter en ajoutant les annotations Getter et Setter au niveau de la classe. Ainsi les fonctions seront disponibles pour toutes les variables, comportement illustré par la classe DataObject.

package fr.ejn.tutorial.java.lombok.accessors;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

/**
 * Tutorial class to illustrate getters and setters on class level.
 *
 * @author Etienne Jouvin
 *
 */
@Getter
@Setter
public class DataChainFieldSetterObject {

  private @Accessors(chain = true) String name;
  private String surname;

}

Le test unitaire correspondant, ie DataChainFieldSetterObjectTest montre la mise à disposition des fonctions en testant les valeurs spécifiées.

package fr.ejn.tutorial.java.lombok.accessors;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class DataChainFieldSetterObjectTest {

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
  }

  @Before
  public void setUp() throws Exception {
  }

  @After
  public void tearDown() throws Exception {
  }

  @Test
  public void testChain() throws Exception {
    DataChainFieldSetterObject actual = new DataChainFieldSetterObject().setName("data name");
    actual.setSurname("data surname");

    assertThat(actual.getName()).isEqualTo("data name");
    assertThat(actual.getSurname()).isEqualTo("data surname");
  }

}

Robot-icon.png Enchaînement

A noter l'ajout de l'annotation Accessors avec la valeur true pour l'argument chain pour la variable name dans le précédent exemple. Dans ce cas, le setter n'est pas une simple méthode mais une fonction qui retourne l'instance en cours, illustrer lors de la construction de la variable actual dans le test unitaire.

Mais il est également possible de positionner cette annotation au niveau de la classe. Ainsi tous les setter générés retourneront l'instance. Ceci peut être pratique pour enchaîner les affectations de valeurs, comme dans le cas de la classe d'exemple DataChainSetterObject.

package fr.ejn.tutorial.java.lombok.accessors;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

/**
 * Tutorial class to illustrate the setters that return the current instance. Setters can be called
 * in chain like this.
 *
 * @author Etienne Jouvin
 *
 */
@Getter
@Setter
@Accessors(chain = true)
public class DataChainSetterObject {

  private String name;
  private String surname;

}

Dans le test unitaire correspondant, DataChainSetterObjectTest, l'instance a tester est construire en appelant tous les setter

package fr.ejn.tutorial.java.lombok.accessors;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class DataChainSetterObjectTest {

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
  }

  @Before
  public void setUp() throws Exception {
  }

  @After
  public void tearDown() throws Exception {
  }

  @Test
  public void testChain() throws Exception {
    DataChainSetterObject actual = new DataChainSetterObject().setName("data name")
        .setSurname("data surname");

    assertThat(actual.getName()).isEqualTo("data name");
    assertThat(actual.getSurname()).isEqualTo("data surname");
  }

}


Multiples-icon.png Choix variable

Dans les précédents exemples, les annotations sont placées au niveau de la classe, entraînant la génération des fonctions pour toutes les variables. Il est également possible de les, Getter et Setter, positionner au niveau des variables pour choisir lesquelles seront élligibles. La classe DataObjectSpecificFields illustre ce fonctionnement en choisissant uniquement une variable pour laquelle le setter est généré, les getter restant au niveau de la classe.

package fr.ejn.tutorial.java.lombok.accessors;

import lombok.Getter;
import lombok.Setter;

/**
 * Tutorial class to illustrate Data annotation, that inject getter / setter / equals and toString.
 *
 * @author Etienne Jouvin
 *
 */
@Getter
public class DataObjectSpecificFields {

  private @Setter String name;
  private String surname;

  /**
   * Constructor with the surname to set.
   *
   * @param surname Surname to set.
   */
  public DataObjectSpecificFields(String surname) {
    this.surname = surname;
  }

}

Le test unitaire correspondant, DataObjectSpecificFieldsTest permet de valider que seul le getter pour name est disponible. Afin de valider le getter, la variable surname doit être renseignée lors de la construction de l'instance.

package fr.ejn.tutorial.java.lombok.accessors;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class DataObjectSpecificFieldsTest {

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
  }

  @Before
  public void setUp() throws Exception {
  }

  @After
  public void tearDown() throws Exception {
  }

  @Test
  public void testAccessors() {
    DataObjectSpecificFields actual = new DataObjectSpecificFields("data surname");
    actual.setName("data name");

    assertThat(actual.getName()).isEqualTo("data name");
    assertThat(actual.getSurname()).isEqualTo("data surname");
  }

}


Examples-icon.png Raccourci Data

L'annotation Data permet d'"englober" les deux annotations Getter et Setter, mais également des annotations permettant de faciliter l'égalité et la représentation en String de l'objet, comme illustré par la classe DataObject

package fr.ejn.tutorial.java.lombok.accessors;

import lombok.Data;

/**
 * Tutorial class to illustrate Data annotation, that inject getter / setter / equals and toString.
 *
 * @author Etienne Jouvin
 *
 */
@Data
public class DataObject {

  private String name;
  private String surname;

}

Le test unitaire correspondant, DataObjectTest, démontre la mise à disposition des fonctions créées.

package fr.ejn.tutorial.java.lombok.accessors;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class DataObjectTest {

  @BeforeClass
  public static void setUpBeforeClass() throws Exception {
  }

  @AfterClass
  public static void tearDownAfterClass() throws Exception {
  }

  @Before
  public void setUp() throws Exception {
  }

  @After
  public void tearDown() throws Exception {
  }

  @Test
  public void testAccessors() {
    DataObject actual = new DataObject();
    actual.setName("data name");
    actual.setSurname("data surname");

    assertThat(actual.getName()).isEqualTo("data name");
    assertThat(actual.getSurname()).isEqualTo("data surname");
  }

  @Test
  public void testEquals() throws Exception {
    DataObject actual = new DataObject();
    actual.setName("data name");
    actual.setSurname("data surname");

    DataObject otherData = new DataObject();
    otherData.setName("data name");
    otherData.setSurname("data surname");
    assertThat(actual.equals(otherData)).isTrue();

    otherData = new DataObject();
    otherData.setName("other data name");
    otherData.setSurname("data surname");
    assertThat(actual.equals(otherData)).isFalse();
  }

  @Test
  public void testToString() throws Exception {
    DataObject actual = new DataObject();
    actual.setName("data name");
    actual.setSurname("data surname");

    String expected = "DataObject(name=data name, surname=data surname)";
    assertThat(actual.toString()).isEqualTo(expected);
  }

}


Viewer icon.png Voir aussi

Documentation officielle: https://projectlombok.org/features/GetterSetter

https://projectlombok.org/features/Data