Invariance+Immutabilité=❤

Invariance

Qu’est-ce que c’est ?

Avec les pré-conditions et les post-conditions, l’invariance est le troisième type de contrat en programmation orientée objet (POO).

L’invariance est une condition qui est toujours vraie dans un contexte donné.

En quoi l’invariance peut-elle aider en programmation orientée objet ?

Démonstration par la pratique

public class Song {
private String title;
private String artistName;
  public Song() {
}
  public void setTitle(String title) {
this.title = title;
}
  public String getTitle() {
return this.title;
}
  public void setArtistName(String artistName) {
this.artistName = artistName;
}
  public String getArtistName() {
return this.artistName;
}
}

Ci-dessus, la classe Song, représente une chanson avec son titre et son artiste.

Cette classe, bien qu’étant une structure de donnée pertinente, elle n’en reste pas moins limitée. Elle se contente de représenter un état sans pouvoir le contrôler. Pourquoi pourrait-on créer une instance de Song ayant un titre de chanson vide ? Ou sans titre d’artiste ?

Voilà donc à quoi sert la notion d’invariance en POO : donner plus de responsabilité à vos objets du domaine. Leur permettre de fixer les limites de leurs propre existence : si j’existe c’est que je suis dans un état cohérent, sinon je n’existe pas.

“To be coherent or not to be”, Will.i.am

Voici une implémentation améliorée de cette classe :

public class Song {
private String title;
private String artistName;
  public Song(String title, String artistName) {
Validate.checkNotEmpty(title);
Validate.checkNotEmpty(artistName);
this.title = title;
this.artistName = artistName;
}
  public void setTitle(String title) {
Validate.checkNotEmpty(title);
this.title = title;
}
  public String getTitle() {
return this.title;
}
  public void setArtistName(String artistName) {
Validate.checkNotEmpty(artistName);
this.artistName = artistName;
}
  public String getArtistName() {
return this.artistName;
}
}

Cette version de Song, a maintenant deux validations dans ses mutateurs assurant que les informations que nous essayons de leur passer sont cohérentes. Mais surtout, elle ne peut plus être instanciée sans fournir des données cohérentes de titre et d’artiste.

Ainsi, les objets de la classe Song sont assurés de toujours se trouver dans des états cohérents.

Pourquoi l’invariance est important ?

  • Il est préférable de recevoir une IllegalArgumentException à l’instanciation d’un objet qu’un NullPointerException à son utilisation.
  • Si vous êtes certains que votre système ne peut pas instancier une chanson sans titre, alors vérifiez le.
  • Les validations d’invariance servent de documentation !
  • C’est un premier pas dans la reflexion sur ce qui importe dans vos objets.

Seulement, bien que l’invariance soit une très bonne pratique, elle est souvent couplée à la notion d’immutabilité.

Immutabilité

Qu’est-ce que c’est ?

Le mot immutabilité est sérieusement un buzz-word utilisé à toutes les sauces ces dernières années (comme peut l’être le terme agilité).

On parle de code immutable, d’infrastructure immutable, de l’immutabilité des builds, de langages de programmation orientés immutabilité.

Mais qu’est ce que l’immutabilité ?

“In object-oriented programming, an object is immutable if its state can’t be modified after it is created.” Jean Valjean, Les misérables

Un cas classique en Java est la classe String, en effet, en Java, on ne change pas l’état de son String.

Démonstration par la pratique

Reprenons notre classe Song, elle nous assure maintenant de ne pouvoir être instanciée que d’objets cohérents. C’est bien !

Mais elle offre trop de possibilités, et pour comprendre où le bât blesse essayons de revenir au concept réel d’une chanson et de se poser les bonnes questions :

  • est-ce qu’une chanson peut changer d’artiste ?
  • est-ce qu’une chanson peut changer de titre ?

Dans le monde réel, les deux réponses à ces questions sont non.

Voici donc une récriture de notre classe Song :

public class Song {
private String title;

public Song(String title, String artistName) {
Validate.checkNotEmpty(title);
Validate.checkNotEmpty(artistName);
this.artistName = artistName;
this.title = title;
}
  public String getTitle() {
return this.title;
}
  public String getArtistName() {
return this.artistName;
}
}

Pourquoi l’immutabilité est important ?

  • Les objets immutables sont plus simples à utiliser et tester.
  • Les objets immutables sont toujours thread-safe.
  • L’immutabilité rend obsolète la définition de clone().

Conclusion

Le temps des DTO est révolu. Quand vous écrivez une classe de votre domaine :

  • Elle devrait être immutable par défaut, et seulement après posez vous la question : qu’est ce qui justifierait que je casse l’immutabilité ? (j’espère rien)
  • Posez vous la question des contrats qu’elle expose et de la cohérence de son état.
One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.