Dans cette séance, j'ai envie de vous montrer comme on
doit utiliser le debugger pour programmer différemment.
On va ré-implémenter l'application counter mais d'une
manière différente, avec un flow de développement plus interactif.
La première chose que je vais faire, je vais créer un
nouveau package avec Counter comme précédemment.
Je vais filtrer aussi parce qu'au moins j'aurai moins de choses.
Dans MyCounter, je vais commencer par définir
un test, une classe de test.
Donc, les classes de test héritent de TestCase.
Je vais l'appeler Counter Test.
Je vais compiler. Je le fais encore une fois au menu et
puis après, je vais le faire avec les commentaires.
Ça m'a créé ma classe de test.
Dans ma classe de test, je vais écrire une méthode de
test. Les méthodes de test commencent par test.
Qu'est -ce que je fais ?
Comme précédemment je définis une variable locale, dans
cette variable locale je vais mettre un
objet de la classe Counter.
Je vais initialiser la valeur de ce Counter et je vais
vérifier que le Counter a la bonne valeur.
Je compile.
Maintenant, le système me dit attention, je ne sais pas
ce que c'est que le Counter. Il me l'avait déjà indiqué
parce que c'était déjà en italique ici.
Il me propose: "Est-ce que tu veux dire définir une nouvelle classe?
Une nouvelle globale ou une variable de classe?"
Moi c'est une nouvelle classe.
Là, il me propose la définition de la classe qui pourrait définir.
Je dis, oui c'est correct, dans le bon package, ça hérite
d'object, très bien, fais-le.
Et là, il a crée une classe vide.
Maintenant, on va reclasser ça.
Maintenant ce que je peux voir ma classe Counter est vide.
Maintenant si j'exécute mon test, il est rouge.
Pourquoi est-il rouge ?
Parce que j'ai une erreur.
Alors comment je dois lire ce message?
Prenons 2 minutes pour faire ça.
Le système me dit: "un message Count a été envoyé à
une instance de la classe Counter et on n'a pas trouvé la
méthode qui correspond". Je vais regarder.
J'ouvre le debugger.
Le débugger me présente la pile d'exécution, donc je peux
voir et il me montre qu'il y a eu un message qui n'a pas été compris.
Et là, il me montre l'endroit où ce message a été invoqué.
Ce que je vois, c'est que si je viens ici, je vois les
variables du système, si je regarde C, ça me permet d'accéder
à la variable temporaire C, qui elle, vaut un Counter.
De toute façon, si je fais C class par exemple,
selfclass, il me dit c'est la classe Counter.
C'est évident. Pour le moment, dans ma classe, je n'ai
pas de méthode. Je vais demander au système d'en créer une pour moi.
Je vais dire Create.
Il me propose dans quelle classe.
Je vais dire dans la classe Counter.
Est-ce que tu peux créer cela ?
Je fais oui dans Accessing.
Et là, qu'est-ce qu'il a fait finalement?
Il a compilé automatiquement une méthode avec la bonne signature.
Pour le corps de la méthode, il ne sait pas quoi faire,
donc il utilise ShouldBeImplemented. Qu'est-ce que ça fait?
Ça va lever une exception à l'exécution et le système a
ré-exécuté cette méthode.
Maintenant, j'ai une nouvelle erreur et je dois
implémenter le corps de la méthode.
Je sais Count. Qu'est-ce que je vais faire?
J'ai envie de stocker cette variable, cette valeur dans
une variable d'instance. Donc là
c'est rouge, parce que pour le moment ma classe n'a pas cette instance.
Je vais faire Compile.
Le système me propose: "Est-ce que tu veux une variable
temporaire ou une variable d'instance?"
Je veux une variable d'instance.
Donc je fais ça. Si je regarde dans ma classe, j'ai bien
une variable d'instance Count qui a été créée et la
méthode, le Setter qui va bien mettre
la valeur.
Une fois que j'ai fait ça, je peux dire au debugger
continue, Proceed, ça veut dire continue l'exécution
comme si de rien n'était.
Qu'est ce qui se passe ?
J'ai encore une erreur.
Le système me dit toujours, il y a une instance de la
classe Counter qui a reçu le message count et je n'ai pas
trouvé la bonne méthode. C'est normal parce que si je
regarde C, je peux voir que C a bien 7
dans son Counter, dans sa variable count, mais par contre
la méthode count n'existe pas.
Je vais la recréer.
Je vais faire Create, Dans quelle classe?
Toujours la classe Counter, dans le protocole accessing
car c'est un accesseur. Et là, ce que vous
voyez, c'est que le système est un peu plus intelligent.
Il s'est dit qu'il y avait une variable d'instance qui s'appelait
count, il veut définir une méthode qui s'appelle count
donc proposons-lui un accesseur.
C'est ce que je voulais.
Donc là maintenant je peux donc faire Proceed.
Qu'est-ce que je vois ?
Mon test est vert. J'ai mon test qui est vert et ma
classe a bien 2 méthodes qui ont été créées.
Maintenant je vais faire la même chose pour increment.
En fait finalement ce que je suis en train de faire c'est
que je suis en train de spécifier ce que la méthode doit
faire, et de vérifier qu'elle le fait bien.
Donc là je dois obtenir 9, je compile, j'exécute.
Et là le système me dit, je ne connais pas la méthode increment.
Oui c'est normal, Je vais faire Create, ici dans opération.
Si je regarde increment, je peux faire count.
= count + 1. Je compile.
Proceed. J'ai bien mon test.
Dans la foulée, on va faire decrement.
L'idée, c'est que vous le fassiez, que vous le pratiquiez.
Donc là ce sera 5. Je définis mon test.
Je crée ma méthode.
OK. Donc à vous commencez à savoir count: = count,
je compile dans le debugger.
Je fais Proceed. Et mes tests sont verts.
Ma classe a maintenant 2 opérations: increment et decrement.
C'est le moment de sauver, par exemple.
Je vais sauver comme je vous l'ai montré précédemment.
Je sauve, je vais faire Save, je sauve et là je vais
lui dire "with
accessors and decrement increment covered by green tests".
Donc voila j'ai sauvé ça,
très bien.
Ce qui est important de voir dans cette session, c'est
que le debugger nous a permis d'accéder à l'état d'
objet, et d'être vraiment dans le contexte d'appel et d'utiliser
ce contexte d'appel pour avoir toutes les informations
nécessaires pour pouvoir écrire notre code.
Et ça, c'est vraiment très, très puissant.