<div dir="ltr">Bonjour,<br><br>Un dictionnaire mais seulement si il est déclaré une fois pour toute.<br>Surtout pas un dictionnaire créé et renseigné dans la méthode juste avant son utilisation (trop lourd).<br><br>En regardant d&#39;un peu plus près l&#39;exemple de la direction on se rend compte qu&#39;on veut passer d&#39;une représentation d&#39;un concept sur un autre concept ou sur une autre représentation. Ici, on veut passer d&#39;une représentation du concept de direction sous forme de symbole vers une représentation sous forme de Point (ou plutôt de Vecteur).<br>
<br>Le réflexe qu&#39;on doit avoir selon moi c&#39;est de ce demander si on n&#39;est pas passé à coté d&#39;un objet. Effectivement, ici on manipule un concept de Direction qui n&#39;est pas clairement défini en tant qu&#39;objet. Il est donc probable que mon code serait plus &quot;Orienté Objet&quot; avec une classe Direction. Dans notre cas présent, il semble qu&#39;on gère 4 directions particulières (haut, bas, droite et gauche). Il semble donc intéressant de spécifier 4 instances particulières, constantes, qu&#39;on placera certainement dans des variables de classe ou dans des variables d&#39;instances de classes. Peu importe la manière de conserver ces instances, il estprobable que j&#39;aurai envie de proposer un accès à ces instances et donc je placerai des méthodes de classe comme haut, bas, droite et gauche dans ma classe Direction.<br>
<br>Que sait faire un objet Direction ? Certainement un tas de choses comme me donner un vecteur sous forme d&#39;un Point (la méthode vector dont parle Damien dans un message précédent). On peut se contenter dans un premier temps de conserver cette information dans un attribut d&#39;instance propre à chaque instance de Direction.<br>
Si le comportement des objets Direction devait vraiment être très différent selon l&#39;instance, on pourrait effectivement envisager de faire des sous classes pour chaque direction mais on n&#39;a peut être pas besoin d&#39;aller jusque là pour cet exemple (faire des hiérarchies de classes complique souvent les choses).<br>
<br>Est-ce que cela élimine tous besoin d&#39;un switch ? la réponse est malheureusement non.<br>Il y a forcément un moment où je vais devoir récupérer une instance et où je vais me demander laquelle. Par exemple si je dois récupérer l&#39;instance correspondant à un caractère frappé au clavier ou si je veux implémenté une méthode comme #normal donnant la direction à 90 degrés. Une possibilité est d&#39;ajouter une information dans la classe Direction et d&#39;offrir accès à la liste des instances (ici des quatres constantes). Ainsi, je peux faire une recherche dans cette collection. Par exemple, on peut ajouter l&#39;information #name et donc faire une boucle de recherche par nom sur cette collection. Si ce besoin est fréquent, on va certainement offrir une méthode d&#39;accès effectuant cette recherche, ce qui pourrait donner :<br>
<br>directionNamed: aSymbol<br>&nbsp;&nbsp;&nbsp; &quot;answer the constant named aSymbol or raise an exception&quot;<br><br>&nbsp;&nbsp;&nbsp; ^self directions detect: [:each | each name = aSymbol]<br><br>Evidemment, il est tentant de faire un #perform: (à déconseiller vivement car on ne contrôle plus ce qui se passe avec un symbole quelconque)<br>
directionNamed: aSymbol<br>&nbsp;&nbsp;&nbsp; &quot;answer the constant named aSymbol or raise an exception&quot;<br><br>&nbsp;&nbsp;&nbsp; ^self perform: aSymbol<br><br>Ca n&#39;est pas toujours souhaitable d&#39;enrichir la classe de cette manière. Il y a toujours des cas où on retombe sur la question &quot;Passer d&#39;un concept à un autre&quot;.<br>
<br>Ici l&#39;exemple de la méthode #normal commencerait à devenir limite (on va pas ajouter à chaque instance un attribut pour donner sa #normal et aussi sa transposé ou son inverse).<br><br>Si on reste dans le cadre des quatres constantes on va donc se faire une séquence de if du genre :<br>
normal<br>&nbsp;&nbsp;&nbsp; &quot;answer the direction rotated 90 deg&quot;&nbsp;&nbsp;&nbsp; <br><br>&nbsp;&nbsp;&nbsp; self == self class haut ifTrue: [^self gauche].<br>&nbsp;&nbsp;&nbsp; self == self class gauche ifTrue: [^self bas].<br>&nbsp;&nbsp;&nbsp; self == self class bas ifTrue: [^self droite].<br>
&nbsp;&nbsp;&nbsp; self == self class droite ifTrue: [^self haut].<br>&nbsp;&nbsp;&nbsp; self error: &#39;You have created other Direction instance !!!&#39;<br><br>Remarque : on pourrait évidemment supporter des instances constantes et non constantes.<br>
<br>Dans ce cas précis on pourrait utiliser un dictionnaire (stocké quelque part dans la classe) et remplaçant la séquence de tests par un accès plus performant (à mesurer)<br>ça pourrait donc donner :<br>normal<br>&nbsp;&nbsp;&nbsp; &quot;answer the direction rotated 90 deg&quot;&nbsp;&nbsp;&nbsp; <br>
<br>&nbsp;&nbsp;&nbsp; ^self class normalsDictionary<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; at: self<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ifAbsent: [self error: &#39;You have created other Direction instance !!!&#39;]<br><br>Que dire de plus ? Expliquer l&#39;intérêt de toute cette prise de tête alors qu&#39;un bon switch semblerait plus simple.<br>
Stéphane donne la réponse. Que se passe-t-il si on veut faire évoluer, par exemple en offrant maintenant les 4 directions supplémentaires hautDroite, hautGauche, basDroite et basGauche.<br>L&#39;objectif de tout ça est de diminuer les impacts sur le code utilisant la classe et si possible de faire en sorte que les impacts ne soient que des ajouts (de classes ou de méthodes) et non des modifications de méthodes existantes.<br>
<br>Faire des switch dans son code client implique de prendre en compte les nouveaux cas. <br>L&#39;exemple de départ était la méthode <br>vitesseVers: dir<br>&nbsp;&nbsp; dir==#Haut ifTrue [vitesse := 0@1].<br>&nbsp;&nbsp; dir==#Bas ifTrue [vitesse := 0@-1].<br>
&nbsp;&nbsp; dir==#Gauche ifTrue [vitesse := -1@].<br>&nbsp;&nbsp; dir==#Droite ifTrue [vitesse := 0@-1].<br><br>On voit bien que la prise en compte de quatre nouvelles directions impose de modifier cette méthode et certainement tout un tas d&#39;autre. <br>
<br>Proposer des alternatives (dictionnaires par exemple) avec des vrais objets permet de déporter ces switch dans un unique endroit (la classe Direction). Ca devient la responsabilité du développeur de cette classe de maintenir la cohérence des dictionnaires (ici le normalsDictionary par exemple) et non celle du client de se maintenir à jour.<br>
<br>Bon, je voulais mettre mon grain de sel et voilà que j&#39;ai versé tout le paquet. Désolé pour la longueur<br><br>Jean-François<br><br><div class="gmail_quote">Le 28 septembre 2008 13:47, stephane ducasse <span dir="ltr">&lt;<a href="mailto:stephane.ducasse@free.fr" target="_blank">stephane.ducasse@free.fr</a>&gt;</span> a écrit :<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
un dictionaire cela veut dire que l&#39;on peut etendre le comportement sans copier copier et modifier tous les cases.<br>
<br>
stef<div><div></div><div><br>
On Sep 28, 2008, at 1:33 PM, Stéphane Rollandin wrote:<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Damien Pollet a écrit :<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
2008/8/26 Stéphane Rollandin &lt;<a href="mailto:hepta@zogotounga.net" target="_blank">hepta@zogotounga.net</a>&gt;:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
sans doute, mais c&#39;est la seule réponse techniquement correcte à la question<br>
posée: quel est l&#39;équivalent du switch.<br>
</blockquote>
le switch c&#39;est le message lookup :)<br>
</blockquote>
<br>
non, pas du point de vue pratique. utiliser un dictionaire, ok (mais en fin de compte quelle est la différence conceptuelle entre implémenter un lookup via une classe, dictionaire, et une méthode, caseOf: ? pourquoi l&#39;un sortirait des clous &quot;c&#39;est de l&#39;objet&quot; et pas l&#39;autre ?)<br>


<br>
en revanche, implémenter un message pour #haut, #bas, etc... ça ce serait vraiment du mauvais design objet AMHA.<br>
<br>
Stef<br>
<br>
_______________________________________________<br>
Squeak-fr mailing list<br>
<a href="mailto:Squeak-fr@lists.squeakfoundation.org" target="_blank">Squeak-fr@lists.squeakfoundation.org</a><br>
<a href="http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr" target="_blank">http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr</a><br>
<br>
</blockquote>
<br>
_______________________________________________<br>
Squeak-fr mailing list<br>
<a href="mailto:Squeak-fr@lists.squeakfoundation.org" target="_blank">Squeak-fr@lists.squeakfoundation.org</a><br>
<a href="http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr" target="_blank">http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/squeak-fr</a><br>
</div></div></blockquote></div><br></div>