"Redo : initialisation d'objets"
Quentin Ducasse.
-Bonjour à tous.
Dans cette cinquième partie du Redo, on va s'intéresser
à la manière correcte d'initialiser vos objets.
Jusqu'à présent, on a appelé la méthode "new" sur la classe qu'on veut
et on a attribué notre variable d'instance en utilisant nos accesseurs.
Que se passe-t-il si on appelle simplement "c increment"
et qu'on exécute tout ça ?
Cmd+P.
On voit que la méthode "+" a été envoyée à nil.
Ça signifie que count vaut nil.
Count, c'est notre variable d'instance et elle n'est jamais initialisée.
Par défaut, Pharo va lui donner la valeur de nil.
C'est un comportement qui ne nous intéresse pas trop.
On aimerait avoir une valeur de zéro à la création de notre objet.
Donc, on va écrire une classe qui correspond à ma dernière phrase,
c'est-à-dire une valeur de zéro à l'initialisation.
On va l'appeler "testInitialize".
On va garder la création et on veut que, juste après la création,
si on s'intéresse à la variable d'instance,
elle vaille directement zéro.
On sauvegarde. Très bien, testInitialize.
Donc, la méthode a été créée.
Si on clique sur le bouton gris, elle devrait échouer,
car on n'a rien changé au comportement
et la variable d'instance vaut toujours nil au lieu de 0.
La méthode qu'il faut créer pour changer ce comportement à la création
s'appelle "initialize".
C'est une bonne pratique de mettre une première expression
qui soit "super initialize"
pour aller appeler les méthodes d'initialisation des super classes,
puis le comportement qu'on veut.
On veut que "count" soit égal à zéro.
On peut sauvegarder ça.
On voit qu'il a détecté le test qui lui est associé.
Si on lance le test, il est réussi.
Maintenant, on a une initialisation de notre variable d'instance
qui, juste après la création de l'objet, est zéro.
Imaginons qu'on veuille créer un compteur
qui ait, par défaut, une variable d'instance count qui vaille 5.
On peut faire ça en utilisant une méthode de classe.
Si on écrit le test associé dans CounterTest,
on va créer "testStartingAtFive".
On va vouloir créer notre variable temporaire "c",
"c" sera égal à un nouveau compteur,
sauf que cette fois, pour créer le compteur,
on va utiliser une méthode qui va s'appeler startingAt
à laquelle on va donner un entier, 5.
Maintenant, on va pouvoir vérifier avec la même vérification que tout à l'heure
que "c count" soit égal à 5.
Si on sauvegarde ce test, il n'a pas de raison de marcher,
puisque "startingAt" n'a pas été défini.
Donc on voit déjà un panneau interdit qui nous prévient que ça ne marchera pas.
Mais si on l'exécute, on voit qu'on a bien l'erreur,
que la classe compteur n'a pas compris "startingAt".
On va devoir créer cette méthode de classe.
Pour ce faire, on se redirige dans la classe compteur.
On va sur l'onglet Class side.
Là, on est dans l'environnement où les méthodes de test sont définies.
On peut sélectionner ici
et créer notre méthode "startingAt:" un entier
qui va nous renvoyer un nouveau compteur, "self new"
auquel on aura attribué la valeur de l'entier qu'on vient de placer.
Ça va nous créer un nouveau compteur.
Dans ce nouveau compteur,
la variable d'instance va avoir la valeur anInteger.
On peut sauver ça.
Maintenant, si on réexécute nos tests, on voit qu'ils passent.
Ils sont tous verts.
Donc on va écrire un dernier test
pour englober toutes les méthodes qu'on a pu définir.
Donc, on va l'appeler "testAllMethods".
On va créer notre compteur
et on va vérifier que self, c'est "(increment ; count) equals: 6".
On va sauvegarder. Notre méthode TestAllMethods est là.
Si on l'exécute, on voit qu'elle fonctionne.
Donc on a pu tester à la fois l'initialisation à 5
puis l'incrémentation et on voit que les deux fonctionnent bien.
Si on reclique sur le bouton vert, les six tests viennent de passer.
C'est un bon moment pour commit ce qu'on a pu changer dans Iceberg.
On se dirige ici. On commit.
Et on peut marquer : "Added initialization methods (tested)".
Et on va pouvoir commit.
Donc, on a appris comment initialiser correctement un objet
et comment utiliser des méthodes de classe
pour nous donner des objets prégénérés avec des valeurs intéressantes.