1
00:00:00,790 --> 00:00:04,120
Bonjour à tous. Dans cette
séquence, nous allons discuter

2
00:00:04,320 --> 00:00:06,260
des messages et on va
voir pourquoi avoir plein de

3
00:00:06,460 --> 00:00:08,140
messages partout et des
toutes petites méthodes, c'est

4
00:00:08,340 --> 00:00:10,250
vraiment bien
contrairement à ce que beaucoup de

5
00:00:10,450 --> 00:00:15,350
développeurs peuvent
penser. C'est une séquence

6
00:00:15,550 --> 00:00:18,850
de conception qui est
valable non seulement pour Pharo,

7
00:00:19,050 --> 00:00:21,860
mais pour la conception
dans tous les langages objet.

8
00:00:23,900 --> 00:00:26,900
Comme nous l'avons vu, les
envois de messages, ce sont

9
00:00:27,100 --> 00:00:30,280
des hooks, des endroits où on va
pouvoir passer du comportement.

10
00:00:31,400 --> 00:00:34,170
Beaucoup de développeurs
disent régulièrement "J'aime

11
00:00:34,370 --> 00:00:38,150
bien les grosses méthodes parce
que c'est facile à comprendre.

12
00:00:38,350 --> 00:00:40,910
Il suffit de lire ligne à
ligne et je comprends le code.

13
00:00:41,110 --> 00:00:44,150
" Et en fait, dans cette
séquence-là, je vais vous

14
00:00:44,350 --> 00:00:47,140
montrer que ce n'est
vraiment pas un bon point et qu'en

15
00:00:47,340 --> 00:00:49,840
général, les grosses méthodes
sont des problèmes de design.

16
00:00:51,230 --> 00:00:54,290
Avoir une hiérarchie de
 classes et une même méthode

17
00:00:54,490 --> 00:00:57,730
implémentée dans plusieurs classes,
c'est une façon de faire du choix.

18
00:00:59,230 --> 00:01:03,370
Si on prend une grosse
 classe avec plein d'opérations et

19
00:01:03,570 --> 00:01:07,310
qu'il faut choisir l'opération en
fonction de l'état, je vais mettre quoi?

20
00:01:07,510 --> 00:01:09,570
Je vais avoir du code qui
ressemble à "Si je suis dans

21
00:01:09,770 --> 00:01:11,290
cet état-là, alors je
fais cette opération.

22
00:01:11,490 --> 00:01:13,150
Là, si je suis dans cet
état-là, je fais cette

23
00:01:13,350 --> 00:01:16,520
opération", et on va avoir
tendance à avoir du gros code

24
00:01:17,260 --> 00:01:19,000
avec des "if" partout.

25
00:01:19,180 --> 00:01:22,150
Ce qui fait que quand on
veut ajouter de nouveaux cas, il

26
00:01:22,350 --> 00:01:23,940
faut modifier plein
de méthodes partout.

27
00:01:25,720 --> 00:01:30,600
Dans la version à droite, chaque cas

28
00:01:30,910 --> 00:01:32,900
est séparé dans une classe dédiée.

29
00:01:34,790 --> 00:01:39,580
Il suffit d'envoyer le
message opération à un

30
00:01:39,780 --> 00:01:42,700
objet pour que le if se fasse
et le if n'a pas besoin d'être

31
00:01:42,900 --> 00:01:47,530
écrit par le programmeur, ça se fait

32
00:01:47,730 --> 00:01:49,960
automatiquement grâce au
mécanisme de polymorphisme.

33
00:01:50,930 --> 00:01:52,850
Dans les slides qui
suivent, je vais vous montrer un

34
00:01:53,050 --> 00:01:56,210
exemple et comment je
peux améliorer un exemple en

35
00:01:56,410 --> 00:01:57,390
changeant petit bout par petit bout.

36
00:01:58,930 --> 00:02:01,510
Là, j'ai une grosse
méthode un petit peu difficile à

37
00:02:01,710 --> 00:02:03,310
comprendre qui fait
pas mal de choses.

38
00:02:03,800 --> 00:02:07,460
Ce qu'on aimerait, c'est que
dans une sous-classe, cette

39
00:02:08,110 --> 00:02:11,590
variable qui est là ait une
valeur un petit peu différente.

40
00:02:12,870 --> 00:02:15,950
Tel que le code se trouve,
la seule solution pour faire

41
00:02:16,150 --> 00:02:18,680
ça, d'abord, c'est de faire
la sous-classe et ensuite de

42
00:02:18,880 --> 00:02:22,000
recopier l'ensemble du
code en faisant la petite

43
00:02:22,200 --> 00:02:23,720
modification que l'on souhaite faire.

44
00:02:24,870 --> 00:02:28,360
Dans les langages comme
Java ou avec l'utilisation de

45
00:02:28,560 --> 00:02:32,000
mots-clés private, si les
attributs utilisés par la

46
00:02:32,200 --> 00:02:34,520
méthode sont private, ce que je
viens de faire, ce n'est pas possible.

47
00:02:35,110 --> 00:02:39,350
Si une méthode utilise des
variables d'instances private,

48
00:02:39,550 --> 00:02:41,380
les sous-classes ne
peuvent pas ré implémenter ou

49
00:02:41,580 --> 00:02:44,510
dupliquer le code, donc ça
peut ne pas être possible.

50
00:02:44,710 --> 00:02:46,160
Mais de toute façon,
dupliquer, ce n'est pas une bonne

51
00:02:46,360 --> 00:02:50,470
pratique parce que la
duplication copie les bugs.

52
00:02:50,670 --> 00:02:52,340
Si j'avais un bug dans la
version d'origine, je vais

53
00:02:52,540 --> 00:02:54,200
avoir un bug dans chaque
copie, ce n'est pas très bon.

54
00:02:55,920 --> 00:02:58,210
Et dès que je vais modifier
une copie, il va falloir que

55
00:02:58,410 --> 00:03:00,280
je modifie toutes les duplications.

56
00:03:01,610 --> 00:03:03,380
Ce n'est pas très bon, c'est
du travail en plus pour les

57
00:03:03,580 --> 00:03:06,580
développeurs et il faut se
souvenir qu'il y a plusieurs copies, etc.

58
00:03:09,000 --> 00:03:11,810
La solution, c'est les
messages et l'envoi de messages.

59
00:03:12,580 --> 00:03:14,950
L'idée, c'est que quand,
dans une méthode, on va envoyer

60
00:03:15,150 --> 00:03:17,860
un message plutôt que
d'écrire le contenu de la méthode

61
00:03:18,060 --> 00:03:20,580
correspondante
directement à l'intérieur, les

62
00:03:20,780 --> 00:03:22,400
sous-classes vont pouvoir
modifier le comportement.

63
00:03:24,390 --> 00:03:29,180
Si je prends la méthode bar,
elle envoie foo à self, dans

64
00:03:29,380 --> 00:03:32,470
A, foo retourne 10 et les
sous-classes peuvent changer

65
00:03:33,070 --> 00:03:36,310
cette valeur-là et
mettre par exemple 42.

66
00:03:37,510 --> 00:03:40,140
Comment est-ce qu'on peut
améliorer le code qu'on vient

67
00:03:40,340 --> 00:03:44,160
de voir de façon à pouvoir
profiter du mécanisme d'héritage

68
00:03:44,890 --> 00:03:46,640
sans faire de la duplication ?

69
00:03:46,840 --> 00:03:49,380
Cette partie-là, je vais
l'extraire dans une méthode et à

70
00:03:49,580 --> 00:03:50,740
la place, je vais envoyer un message.

71
00:03:51,000 --> 00:03:53,160
Il existe un refactoring qui
s'appelle extract method qui

72
00:03:53,360 --> 00:03:55,530
fait exactement ça. Vous
avez des outils pour transformer

73
00:03:55,730 --> 00:04:00,670
ce code-là en ce
code-là. Le code que j'avais

74
00:04:00,870 --> 00:04:04,470
sélectionné au slide
d'avant a été transféré dans une

75
00:04:04,670 --> 00:04:05,520
nouvelle méthode qui s'appelle ratio.

76
00:04:07,900 --> 00:04:12,020
Et là où le code était écrit, on
a maintenant un envoi de messages.

77
00:04:13,340 --> 00:04:17,650
Ce qui signifie que dans
les sous-classes, je peux

78
00:04:17,850 --> 00:04:22,370
changer
complètement ce comportement ou

79
00:04:22,570 --> 00:04:26,800
rappeler le comportement de la
super classe et faire une modification.

80
00:04:27,020 --> 00:04:28,000
C'est ce que je fais ici.

81
00:04:28,800 --> 00:04:32,860
J'envoie le message ratio à
super pour exécuter le code

82
00:04:33,550 --> 00:04:35,890
tel qu'il est dans la super
 classe et j'ajoute 10, c'est

83
00:04:36,090 --> 00:04:37,330
ce que je voulais faire au départ.

84
00:04:39,940 --> 00:04:43,800
Une autre étape
possible, c'est d'extraire cette

85
00:04:44,000 --> 00:04:47,000
partie-là de la même façon
pour laisser les sous-classes

86
00:04:47,200 --> 00:04:49,120
pouvoir changer ce comportement-là.

87
00:04:50,500 --> 00:04:54,280
J'extrais ce bout de
code dans une méthode

88
00:04:54,910 --> 00:04:59,100
dédiée et, dans la méthode
principale, j'envoie un message.

89
00:05:02,230 --> 00:05:06,960
Ici, on voit que la classe à
instancier est écrite en dur.

90
00:05:07,760 --> 00:05:09,550
Ce qui fait que les
sous-classes, si elles veulent

91
00:05:09,750 --> 00:05:12,280
changer cette classe-là
pour avoir potentiellement une

92
00:05:12,480 --> 00:05:16,270
sous-classe de uiNode, il va
falloir qu'elles recopient l'ensemble

93
00:05:16,470 --> 00:05:18,910
de cette méthode. On peut
faire exactement le même

94
00:05:19,110 --> 00:05:24,030
processus et extraire la
 classe dans une méthode de façon

95
00:05:24,230 --> 00:05:27,390
à ce que les sous-classes
puissent changer la classe à instancier.

96
00:05:27,590 --> 00:05:28,350
C'est ce que je fais ici.

97
00:05:29,100 --> 00:05:31,930
J'extrais la partie qui
m'intéresse dans une méthode.

98
00:05:34,820 --> 00:05:36,460
Et ici, j'envoie un message.

99
00:05:36,930 --> 00:05:38,710
Du fait que j'envoie un
message, les sous-classes vont

100
00:05:38,910 --> 00:05:39,890
pouvoir changer le comportement.

101
00:05:41,050 --> 00:05:43,030
Il y a des développeurs,
comme je vous l'ai dit au début,

102
00:05:43,500 --> 00:05:47,870
qui ne seront pas d'accord
parce qu'ils trouvent que c'est

103
00:05:48,070 --> 00:05:50,480
difficile de lire plein de
petites méthodes qui sont

104
00:05:50,680 --> 00:05:52,110
réparties un petit peu
partout dans le système et qui

105
00:05:52,310 --> 00:05:53,930
préfèrent lire une
grosse méthode ligne à ligne.

106
00:05:54,910 --> 00:05:56,730
En fait, ça n'est pas une
bonne pratique parce que lire

107
00:05:56,930 --> 00:06:01,750
du code ligne à ligne, si
l'application est très grosse,

108
00:06:01,950 --> 00:06:03,840
on va bien se rendre
compte que l'on ne peut pas lire

109
00:06:04,040 --> 00:06:05,480
ligne à ligne, on ne peut
pas comprendre ce qui se passe.

110
00:06:06,000 --> 00:06:09,600
C'est là que les abstractions
sont utiles et c'est là qu'extraire

111
00:06:09,800 --> 00:06:11,390
des bouts de comportement
des expressions dans des

112
00:06:11,590 --> 00:06:13,850
méthodes va faire du sens
parce qu'on va pouvoir lire

113
00:06:14,150 --> 00:06:16,870
globalement une méthode sans en
comprendre chacun des détails.

114
00:06:18,340 --> 00:06:21,060
Les petites méthodes, c'est vraiment
bien et il faut l'utiliser partout.

115
00:06:22,810 --> 00:06:27,730
On peut continuer.
Ici, on voit qu'on a la

116
00:06:27,930 --> 00:06:31,580
valeur à 55 qui apparaît
en dur dans le code de la

117
00:06:31,780 --> 00:06:33,250
méthode, ce qui signifie que
les sous-classes ne peuvent

118
00:06:33,450 --> 00:06:35,900
pas changer et ne peuvent
pas mettre 100 par exemple.

119
00:06:36,220 --> 00:06:39,320
Donc, on peut extraire cette
valeur-là comme on l'a fait

120
00:06:39,520 --> 00:06:44,250
précédemment et mettre ça
dans une méthode séparée de

121
00:06:44,450 --> 00:06:46,050
façon à ce que les
sous-classes changent cette valeur-là.

122
00:06:47,830 --> 00:06:50,650
Un autre avantage de ça,
c'est qu'avant, il y avait

123
00:06:50,850 --> 00:06:54,700
marqué 55, maintenant
c'est marqué self averageRatio.

124
00:06:55,170 --> 00:06:58,360
On a remplacé une
valeur numérique par un nom.

125
00:06:58,840 --> 00:07:02,200
Et maintenant je sais à
quoi correspond la valeur 55.

126
00:07:02,400 --> 00:07:03,610
Je sais que c'est averageRatio.

127
00:07:04,700 --> 00:07:07,270
En lisant le code,
je comprends mieux.

128
00:07:07,810 --> 00:07:10,880
Avoir plein de petites méthodes,
ça aide aussi à la lecture du code.

129
00:07:11,670 --> 00:07:15,430
Créer cette méthode
averageRatio pour retourner 55 permet

130
00:07:15,630 --> 00:07:17,540
à toutes les sous-classes
de changer la valeur, mais

131
00:07:17,740 --> 00:07:20,010
comment est-ce qu'on permet
aux utilisateurs de la classe

132
00:07:20,210 --> 00:07:22,470
de changer la valeur aussi ?

133
00:07:22,670 --> 00:07:25,470
Ce qu'on peut faire, c'est
passer par une variable d'instance.

134
00:07:26,720 --> 00:07:30,720
La méthode averageRatio qui
était utilisée dans le slide

135
00:07:30,920 --> 00:07:32,950
précédent, maintenant, elle
va retourner la valeur de la

136
00:07:33,150 --> 00:07:36,030
variable d'instance s'il y a
une valeur dedans, sinon ça

137
00:07:36,230 --> 00:07:38,380
retourne la valeur par défaut.

138
00:07:39,060 --> 00:07:40,690
La valeur par défaut, c'est 55.

139
00:07:42,300 --> 00:07:46,510
Les utilisateurs d'un objet
Node vont pouvoir mettre la

140
00:07:46,710 --> 00:07:47,850
valeur qu'ils
souhaitent à l'intérieur.

141
00:07:48,620 --> 00:07:52,280
Avec cette conception, les
sous-classes peuvent faire un

142
00:07:52,480 --> 00:07:56,150
override de la méthode
defaultAverageRatio pour changer la valeur.

143
00:07:56,560 --> 00:07:58,840
Et les utilisateurs de la
 classe peuvent aussi changer la

144
00:07:59,040 --> 00:08:01,030
valeur pendant
l'exécution du programme.

145
00:08:02,230 --> 00:08:03,720
C'est ce qu'on appelle le
gruyère-oriented programming

146
00:08:05,490 --> 00:08:09,850
dans le sens où le
 programme objet ou une méthode va

147
00:08:10,050 --> 00:08:12,870
comporter des trous, on
appelle ça des hooks, qui vont

148
00:08:13,070 --> 00:08:15,710
pouvoir être remplis
par les sous-classes.

149
00:08:16,900 --> 00:08:21,150
En conclusion, le code
peut être réutilisé et raffiné

150
00:08:21,350 --> 00:08:22,110
dans les sous-classes.

151
00:08:22,540 --> 00:08:25,640
À chaque fois qu'on va
envoyer des messages, les

152
00:08:25,840 --> 00:08:28,810
sous-classes vont pouvoir
changer le comportement de la

153
00:08:29,010 --> 00:08:31,020
super classe ou le raffiner
ou le changer complètement.

154
00:08:32,680 --> 00:08:34,830
Les petites méthodes, c'est
vraiment bien parce que ça

155
00:08:35,030 --> 00:08:38,870
donne des noms à des bouts
d'expressions et parce que ça

156
00:08:39,070 --> 00:08:42,370
laisse aux sous-classes le
choix de changer le comportement.

