Mais quand tu écris switch (monEnum)
{
case c1 : ...
case c2 : ...
other : ...
}
que fais-tu, sinon définir un traitement sur ton enum ?
et tu ne va pas, pour un enum donné, définir des centaines de
traitement (de switch donc) différents sinon c'est qu'il y a un vrai
problème de conception...
Je m'inscrit en faux! [...]
Mais quand tu écris switch (monEnum)
{
case c1 : ...
case c2 : ...
other : ...
}
que fais-tu, sinon définir un traitement sur ton enum ?
et tu ne va pas, pour un enum donné, définir des centaines de
traitement (de switch donc) différents sinon c'est qu'il y a un vrai
problème de conception...
Je m'inscrit en faux! [...]
Mais quand tu écris switch (monEnum)
{
case c1 : ...
case c2 : ...
other : ...
}
que fais-tu, sinon définir un traitement sur ton enum ?
et tu ne va pas, pour un enum donné, définir des centaines de
traitement (de switch donc) différents sinon c'est qu'il y a un vrai
problème de conception...
Je m'inscrit en faux! [...]
J'ai bien lu tous les messages et tout cela est vraiment intéressant.
Je me dis finalement ceci : un enum+switch, ça peut-être opportun s'il
est bien localisé dans une unique classe. Si on finit par le retrouver
dans plusieurs endroits, alors il faut repenser la conception et aller
du côté du polymorphisme. Ça vous semble correct ?
J'ai bien lu tous les messages et tout cela est vraiment intéressant.
Je me dis finalement ceci : un enum+switch, ça peut-être opportun s'il
est bien localisé dans une unique classe. Si on finit par le retrouver
dans plusieurs endroits, alors il faut repenser la conception et aller
du côté du polymorphisme. Ça vous semble correct ?
J'ai bien lu tous les messages et tout cela est vraiment intéressant.
Je me dis finalement ceci : un enum+switch, ça peut-être opportun s'il
est bien localisé dans une unique classe. Si on finit par le retrouver
dans plusieurs endroits, alors il faut repenser la conception et aller
du côté du polymorphisme. Ça vous semble correct ?
Salut,
Francois a écrit :Par "flou", je voulais dire en fait que je n'ai jamais eu l'expérience
réelle et palpable des inconvénients du switch. Mais cela vient du fait
que, étant un simple programmeur du dimanche, mes petits codes n'ont pas
un volume assez important pour rendre palpable cette vérité selon
laquelle le switch c'est pas bien en objet.
Ça n'est pas une vérité absolue. Pour certains problèmes, ça n'a juste
pas de sens d'utiliser le polymorphisme. Imagine que tu aies une classe
Conducteur et une enum FeuTricolore qui peut prendre les valeurs VERT,
ORANGE et ROUGE. Si tu souhaites associer des comportements différents à
ton conducteur selon la couleur du feu, il faut justement utiliser un
switch et pas le polymorphisme.
Il est important que tes APIs restent logiques, et vouloir utiliser le
polymorphisme t'obligerait à ajouter des méthodes à ton feu qui prennent
un conducteur en argument. Or la classe FeuTricolore n'a pas à savoir
qu'il existe une classe Conducteur (C'est au conducteur de se préoccuper
du feu, pas le contraire). Le code qui associe la réaction du conducteur
à la couleur du feu devrait donc logiquement se trouver dans la classe
Conducteur.
Mais il y a juste une chose. Faire du
enum et du switch, c'est associer données et traitements, donc il faut
repenser la chose en objets via le polymorphisme. Mais alors dans ce cas
pourquoi s'embêter avec des enum. Dans ce cas, on fait des vraies
classes et on laisse tomber le enum. En fait, dans votre logique, j'ai
l'impression que les enum n'apportent rien et qu'on pourrait s'en passer
largement puisqu'on en arrive à faire finalement des vraies classes avec
l'héritage et compagnie. À la limite, dans votre logique, vous me diriez
que vous ne voulez pas entendre parler des enum, je trouverais ça plus
cohérent. Remarquez, c'est peut-être le cas d'ailleurs, puisque dans
l'exemple d'implémentation de l'enum Etat, vous n'avez justement pas
utilisé d'enum.
Il faut utiliser des enum quand tu cherches à décrire quelque chose qui
ne peut prendre qu'un nombre fini et connu de valeurs, comme l'état
physique d'un matériau (solide, liquide, gazeux), la couleur d'un feu
tricolore, ou les jours de la semaine. (Utiliser le polymorphisme pour
ce genre de chose n'a pas de sens.)
La documentation de Sun donne des bons exemples d'utilisation des enums :
http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html
Salut,
Francois a écrit :
Par "flou", je voulais dire en fait que je n'ai jamais eu l'expérience
réelle et palpable des inconvénients du switch. Mais cela vient du fait
que, étant un simple programmeur du dimanche, mes petits codes n'ont pas
un volume assez important pour rendre palpable cette vérité selon
laquelle le switch c'est pas bien en objet.
Ça n'est pas une vérité absolue. Pour certains problèmes, ça n'a juste
pas de sens d'utiliser le polymorphisme. Imagine que tu aies une classe
Conducteur et une enum FeuTricolore qui peut prendre les valeurs VERT,
ORANGE et ROUGE. Si tu souhaites associer des comportements différents à
ton conducteur selon la couleur du feu, il faut justement utiliser un
switch et pas le polymorphisme.
Il est important que tes APIs restent logiques, et vouloir utiliser le
polymorphisme t'obligerait à ajouter des méthodes à ton feu qui prennent
un conducteur en argument. Or la classe FeuTricolore n'a pas à savoir
qu'il existe une classe Conducteur (C'est au conducteur de se préoccuper
du feu, pas le contraire). Le code qui associe la réaction du conducteur
à la couleur du feu devrait donc logiquement se trouver dans la classe
Conducteur.
Mais il y a juste une chose. Faire du
enum et du switch, c'est associer données et traitements, donc il faut
repenser la chose en objets via le polymorphisme. Mais alors dans ce cas
pourquoi s'embêter avec des enum. Dans ce cas, on fait des vraies
classes et on laisse tomber le enum. En fait, dans votre logique, j'ai
l'impression que les enum n'apportent rien et qu'on pourrait s'en passer
largement puisqu'on en arrive à faire finalement des vraies classes avec
l'héritage et compagnie. À la limite, dans votre logique, vous me diriez
que vous ne voulez pas entendre parler des enum, je trouverais ça plus
cohérent. Remarquez, c'est peut-être le cas d'ailleurs, puisque dans
l'exemple d'implémentation de l'enum Etat, vous n'avez justement pas
utilisé d'enum.
Il faut utiliser des enum quand tu cherches à décrire quelque chose qui
ne peut prendre qu'un nombre fini et connu de valeurs, comme l'état
physique d'un matériau (solide, liquide, gazeux), la couleur d'un feu
tricolore, ou les jours de la semaine. (Utiliser le polymorphisme pour
ce genre de chose n'a pas de sens.)
La documentation de Sun donne des bons exemples d'utilisation des enums :
http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html
Salut,
Francois a écrit :Par "flou", je voulais dire en fait que je n'ai jamais eu l'expérience
réelle et palpable des inconvénients du switch. Mais cela vient du fait
que, étant un simple programmeur du dimanche, mes petits codes n'ont pas
un volume assez important pour rendre palpable cette vérité selon
laquelle le switch c'est pas bien en objet.
Ça n'est pas une vérité absolue. Pour certains problèmes, ça n'a juste
pas de sens d'utiliser le polymorphisme. Imagine que tu aies une classe
Conducteur et une enum FeuTricolore qui peut prendre les valeurs VERT,
ORANGE et ROUGE. Si tu souhaites associer des comportements différents à
ton conducteur selon la couleur du feu, il faut justement utiliser un
switch et pas le polymorphisme.
Il est important que tes APIs restent logiques, et vouloir utiliser le
polymorphisme t'obligerait à ajouter des méthodes à ton feu qui prennent
un conducteur en argument. Or la classe FeuTricolore n'a pas à savoir
qu'il existe une classe Conducteur (C'est au conducteur de se préoccuper
du feu, pas le contraire). Le code qui associe la réaction du conducteur
à la couleur du feu devrait donc logiquement se trouver dans la classe
Conducteur.
Mais il y a juste une chose. Faire du
enum et du switch, c'est associer données et traitements, donc il faut
repenser la chose en objets via le polymorphisme. Mais alors dans ce cas
pourquoi s'embêter avec des enum. Dans ce cas, on fait des vraies
classes et on laisse tomber le enum. En fait, dans votre logique, j'ai
l'impression que les enum n'apportent rien et qu'on pourrait s'en passer
largement puisqu'on en arrive à faire finalement des vraies classes avec
l'héritage et compagnie. À la limite, dans votre logique, vous me diriez
que vous ne voulez pas entendre parler des enum, je trouverais ça plus
cohérent. Remarquez, c'est peut-être le cas d'ailleurs, puisque dans
l'exemple d'implémentation de l'enum Etat, vous n'avez justement pas
utilisé d'enum.
Il faut utiliser des enum quand tu cherches à décrire quelque chose qui
ne peut prendre qu'un nombre fini et connu de valeurs, comme l'état
physique d'un matériau (solide, liquide, gazeux), la couleur d'un feu
tricolore, ou les jours de la semaine. (Utiliser le polymorphisme pour
ce genre de chose n'a pas de sens.)
La documentation de Sun donne des bons exemples d'utilisation des enums :
http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html
Francois a écrit :
Vous n'êtes pas le premier à me dire cela, loin de là. J'avoue que
pour moi, ça reste floue cette histoire d'éviter les switch.
Moi aussi. Je ne comprends pas trop les puristes qui mettent de l'objet
partout, surtout où il n'en faudrait pas et produisent des systèmes:
- lents et gourmand en mémoire: les objets ont un coût non négligeable
par rapport aux types de base
- non évolutifs parce que le traitement n'est plus localisé à un endroit
facilement modifiable mais dispersé dans 36 classes intiment lié aux
choix de l'algo implémenté. Changer d'algo revient à toucher ces 36
classes, bref à faire un redesign complet (et alors que cela n'aurait pu
n'affecter qu'une seule classe: celle effectuant le traitement.
Bref: les data se dispersent dans l'arbre d'agrégation et c'est très
bien car elles sont utiles à beaucoup, mais faire la même chose
systématiquement pour le traitement peut être mauvais si la granularité
n'est pas bonne. Ainsi choisir de faire une méthode par switch est un
mauvais choix à mon avis.
Un truc simple pour savoir si le découpage est le bon est de regarder si
les méthodes-switch ne sont appelées que depuis un seul point (ce qui
est assez logique vu qu'elles effectue un traitement qui aurait du être
fait par une autre classe). Si c'est le cas, il faudrait voir si le
traitement n'est pas trop spécifique au point d'appel et ne devrait pas
être publié par la classe-enum mais plutôt déplacé à l'endroit où on en
a besoin.
Francois a écrit :
Vous n'êtes pas le premier à me dire cela, loin de là. J'avoue que
pour moi, ça reste floue cette histoire d'éviter les switch.
Moi aussi. Je ne comprends pas trop les puristes qui mettent de l'objet
partout, surtout où il n'en faudrait pas et produisent des systèmes:
- lents et gourmand en mémoire: les objets ont un coût non négligeable
par rapport aux types de base
- non évolutifs parce que le traitement n'est plus localisé à un endroit
facilement modifiable mais dispersé dans 36 classes intiment lié aux
choix de l'algo implémenté. Changer d'algo revient à toucher ces 36
classes, bref à faire un redesign complet (et alors que cela n'aurait pu
n'affecter qu'une seule classe: celle effectuant le traitement.
Bref: les data se dispersent dans l'arbre d'agrégation et c'est très
bien car elles sont utiles à beaucoup, mais faire la même chose
systématiquement pour le traitement peut être mauvais si la granularité
n'est pas bonne. Ainsi choisir de faire une méthode par switch est un
mauvais choix à mon avis.
Un truc simple pour savoir si le découpage est le bon est de regarder si
les méthodes-switch ne sont appelées que depuis un seul point (ce qui
est assez logique vu qu'elles effectue un traitement qui aurait du être
fait par une autre classe). Si c'est le cas, il faudrait voir si le
traitement n'est pas trop spécifique au point d'appel et ne devrait pas
être publié par la classe-enum mais plutôt déplacé à l'endroit où on en
a besoin.
Francois a écrit :
Vous n'êtes pas le premier à me dire cela, loin de là. J'avoue que
pour moi, ça reste floue cette histoire d'éviter les switch.
Moi aussi. Je ne comprends pas trop les puristes qui mettent de l'objet
partout, surtout où il n'en faudrait pas et produisent des systèmes:
- lents et gourmand en mémoire: les objets ont un coût non négligeable
par rapport aux types de base
- non évolutifs parce que le traitement n'est plus localisé à un endroit
facilement modifiable mais dispersé dans 36 classes intiment lié aux
choix de l'algo implémenté. Changer d'algo revient à toucher ces 36
classes, bref à faire un redesign complet (et alors que cela n'aurait pu
n'affecter qu'une seule classe: celle effectuant le traitement.
Bref: les data se dispersent dans l'arbre d'agrégation et c'est très
bien car elles sont utiles à beaucoup, mais faire la même chose
systématiquement pour le traitement peut être mauvais si la granularité
n'est pas bonne. Ainsi choisir de faire une méthode par switch est un
mauvais choix à mon avis.
Un truc simple pour savoir si le découpage est le bon est de regarder si
les méthodes-switch ne sont appelées que depuis un seul point (ce qui
est assez logique vu qu'elles effectue un traitement qui aurait du être
fait par une autre classe). Si c'est le cas, il faudrait voir si le
traitement n'est pas trop spécifique au point d'appel et ne devrait pas
être publié par la classe-enum mais plutôt déplacé à l'endroit où on en
a besoin.
Tu raisonne par les traitements. En objet on raisonne par les
Bref: les data se dispersent dans l'arbre d'agrégation et c'est très
bien car elles sont utiles à beaucoup, mais faire la même chose
systématiquement pour le traitement peut être mauvais si la
granularité n'est pas bonne. Ainsi choisir de faire une méthode par
switch est un mauvais choix à mon avis.
Si la méthode en question est utilisée par beaucoup d'objets, c'est
justement ce qu'il faut faire sinon on duplique beaucoup de code !
Un truc simple pour savoir si le découpage est le bon est de regarder
si les méthodes-switch ne sont appelées que depuis un seul point (ce
qui est assez logique vu qu'elles effectue un traitement qui aurait du
être fait par une autre classe). Si c'est le cas, il faudrait voir si
le traitement n'est pas trop spécifique au point d'appel et ne devrait
pas être publié par la classe-enum mais plutôt déplacé à l'endroit où
on en a besoin.
Tu prends le problème à l'envers car on ne part pas du code mais de la
conception !
C'est donc en conception qu'on se pose la question de comment
implémenter un enum. Je répète que c'est une abstraction comme une
autre. Donc il faut se poser les questions :
- Est-elle très réutilisée par différentes abstractions ? si oui,
utiliser le pattern Strategy pour implémenter l'enum (donc utiliser mon
point de vue)
- Doit-elle posséder des traitements généraux utiles à tous le monde ?
si oui, implémenter l'enum comme une classe.
- Au contraire est-elle très localisée ? si oui, on peut, peut-être,
utiliser un enum simple et un switch
je rappelle que :
1) les enum polymorphes existent en Java.
Voir : http://langrsoft.com/articles/enum2.shtml
2) Toujours en Java, on peut ajouter des méthodes (polymorphes) aux
enums. Ceci devrait poser questions à ceux qui préconisent des switch...
Tu raisonne par les traitements. En objet on raisonne par les
Bref: les data se dispersent dans l'arbre d'agrégation et c'est très
bien car elles sont utiles à beaucoup, mais faire la même chose
systématiquement pour le traitement peut être mauvais si la
granularité n'est pas bonne. Ainsi choisir de faire une méthode par
switch est un mauvais choix à mon avis.
Si la méthode en question est utilisée par beaucoup d'objets, c'est
justement ce qu'il faut faire sinon on duplique beaucoup de code !
Un truc simple pour savoir si le découpage est le bon est de regarder
si les méthodes-switch ne sont appelées que depuis un seul point (ce
qui est assez logique vu qu'elles effectue un traitement qui aurait du
être fait par une autre classe). Si c'est le cas, il faudrait voir si
le traitement n'est pas trop spécifique au point d'appel et ne devrait
pas être publié par la classe-enum mais plutôt déplacé à l'endroit où
on en a besoin.
Tu prends le problème à l'envers car on ne part pas du code mais de la
conception !
C'est donc en conception qu'on se pose la question de comment
implémenter un enum. Je répète que c'est une abstraction comme une
autre. Donc il faut se poser les questions :
- Est-elle très réutilisée par différentes abstractions ? si oui,
utiliser le pattern Strategy pour implémenter l'enum (donc utiliser mon
point de vue)
- Doit-elle posséder des traitements généraux utiles à tous le monde ?
si oui, implémenter l'enum comme une classe.
- Au contraire est-elle très localisée ? si oui, on peut, peut-être,
utiliser un enum simple et un switch
je rappelle que :
1) les enum polymorphes existent en Java.
Voir : http://langrsoft.com/articles/enum2.shtml
2) Toujours en Java, on peut ajouter des méthodes (polymorphes) aux
enums. Ceci devrait poser questions à ceux qui préconisent des switch...
Tu raisonne par les traitements. En objet on raisonne par les
Bref: les data se dispersent dans l'arbre d'agrégation et c'est très
bien car elles sont utiles à beaucoup, mais faire la même chose
systématiquement pour le traitement peut être mauvais si la
granularité n'est pas bonne. Ainsi choisir de faire une méthode par
switch est un mauvais choix à mon avis.
Si la méthode en question est utilisée par beaucoup d'objets, c'est
justement ce qu'il faut faire sinon on duplique beaucoup de code !
Un truc simple pour savoir si le découpage est le bon est de regarder
si les méthodes-switch ne sont appelées que depuis un seul point (ce
qui est assez logique vu qu'elles effectue un traitement qui aurait du
être fait par une autre classe). Si c'est le cas, il faudrait voir si
le traitement n'est pas trop spécifique au point d'appel et ne devrait
pas être publié par la classe-enum mais plutôt déplacé à l'endroit où
on en a besoin.
Tu prends le problème à l'envers car on ne part pas du code mais de la
conception !
C'est donc en conception qu'on se pose la question de comment
implémenter un enum. Je répète que c'est une abstraction comme une
autre. Donc il faut se poser les questions :
- Est-elle très réutilisée par différentes abstractions ? si oui,
utiliser le pattern Strategy pour implémenter l'enum (donc utiliser mon
point de vue)
- Doit-elle posséder des traitements généraux utiles à tous le monde ?
si oui, implémenter l'enum comme une classe.
- Au contraire est-elle très localisée ? si oui, on peut, peut-être,
utiliser un enum simple et un switch
je rappelle que :
1) les enum polymorphes existent en Java.
Voir : http://langrsoft.com/articles/enum2.shtml
2) Toujours en Java, on peut ajouter des méthodes (polymorphes) aux
enums. Ceci devrait poser questions à ceux qui préconisent des switch...
Voir les références que j'ai mentionnées.La documentation de Sun donne des bons exemples d'utilisation des enums :
http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html
La documentation de Sun illustre l'utilisation d'enum. Elle ne renseigne
pas sur leur pertinence...
Voir les références que j'ai mentionnées.
La documentation de Sun donne des bons exemples d'utilisation des enums :
http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html
La documentation de Sun illustre l'utilisation d'enum. Elle ne renseigne
pas sur leur pertinence...
Voir les références que j'ai mentionnées.La documentation de Sun donne des bons exemples d'utilisation des enums :
http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html
La documentation de Sun illustre l'utilisation d'enum. Elle ne renseigne
pas sur leur pertinence...
Re,
Ah ça a l'air cool, pleins de design patterns. Mais on ne sait toujours
pas comment tu stockes l'état du feu si ce n'est une enum.
Voir les références que j'ai mentionnées.La documentation de Sun donne des bons exemples d'utilisation des enums :
http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html
La documentation de Sun illustre l'utilisation d'enum. Elle ne renseigne
pas sur leur pertinence...
C'est implicite. Tu ferais une interface JourDeLaSemaine avec une
implémentation par jour pour décrire les jours de la semaine ? Non. Donc
c'est typiquement un cas pour lequel l'utilisation des enums est pertinent.
Re,
Ah ça a l'air cool, pleins de design patterns. Mais on ne sait toujours
pas comment tu stockes l'état du feu si ce n'est une enum.
Voir les références que j'ai mentionnées.
La documentation de Sun donne des bons exemples d'utilisation des enums :
http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html
La documentation de Sun illustre l'utilisation d'enum. Elle ne renseigne
pas sur leur pertinence...
C'est implicite. Tu ferais une interface JourDeLaSemaine avec une
implémentation par jour pour décrire les jours de la semaine ? Non. Donc
c'est typiquement un cas pour lequel l'utilisation des enums est pertinent.
Re,
Ah ça a l'air cool, pleins de design patterns. Mais on ne sait toujours
pas comment tu stockes l'état du feu si ce n'est une enum.
Voir les références que j'ai mentionnées.La documentation de Sun donne des bons exemples d'utilisation des enums :
http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html
La documentation de Sun illustre l'utilisation d'enum. Elle ne renseigne
pas sur leur pertinence...
C'est implicite. Tu ferais une interface JourDeLaSemaine avec une
implémentation par jour pour décrire les jours de la semaine ? Non. Donc
c'est typiquement un cas pour lequel l'utilisation des enums est pertinent.
Wykaaa a écrit :Tu raisonne par les traitements. En objet on raisonne par les
Ce sont les traitements sur les data qui font le travail et apportent de
la valeur à un soft je pense bien. Il est important que le traitement
soit bien placé dans les choix architecturaux, car si on raisonne sans
se préoccuper des traitements, on a un joli diagramme de classe plein de
joli design patterns mais impraticable par la suite pour ceux qui
doivent tirer parti des data pour faire des traitements efficaces.
> <snip>
Bref: les data se dispersent dans l'arbre d'agrégation et c'est très
bien car elles sont utiles à beaucoup, mais faire la même chose
systématiquement pour le traitement peut être mauvais si la
granularité n'est pas bonne. Ainsi choisir de faire une méthode par
switch est un mauvais choix à mon avis.
Si la méthode en question est utilisée par beaucoup d'objets, c'est
justement ce qu'il faut faire sinon on duplique beaucoup de code !
Ce que je dis c'est que si dans la classe enum les méthodes ne sont
utilisées que par une seule autre classe, c'est qu'alors il y a lieu de
se poser la question de savoir si cette méthode ne devrait pas plutôt
figurer dans la classe qui en a besoin (localiser les traitements).
Un truc simple pour savoir si le découpage est le bon est de regarder
si les méthodes-switch ne sont appelées que depuis un seul point (ce
qui est assez logique vu qu'elles effectue un traitement qui aurait
du être fait par une autre classe). Si c'est le cas, il faudrait voir
si le traitement n'est pas trop spécifique au point d'appel et ne
devrait pas être publié par la classe-enum mais plutôt déplacé à
l'endroit où on en a besoin.
Tu prends le problème à l'envers car on ne part pas du code mais de la
conception !
Quand le code est là (99% des programmes finalement), ou que tu n'es pas
la personne en charge de la conception et ce qu'on te demande c'est de
travailler avec l'existant sans rien casser (la vie de tous les jours
quoi), et bien finalement tu es assez content de pouvoir utiliser l'enum
localement dans un switch plutôt que d'avoir à ajouter une méthode dans
la classe Enum parce que soit tu n'en a pas le droit (politique de
responsabilité: tu sors de ton périmètre), soit tu ne peux pas (pas de
code fourni).
C'est donc en conception qu'on se pose la question de comment
implémenter un enum. Je répète que c'est une abstraction comme une
autre. Donc il faut se poser les questions :
- Est-elle très réutilisée par différentes abstractions ? si oui,
utiliser le pattern Strategy pour implémenter l'enum (donc utiliser
mon point de vue)
- Doit-elle posséder des traitements généraux utiles à tous le monde ?
si oui, implémenter l'enum comme une classe.
- Au contraire est-elle très localisée ? si oui, on peut, peut-être,
utiliser un enum simple et un switch
je rappelle que :
1) les enum polymorphes existent en Java.
Voir : http://langrsoft.com/articles/enum2.shtml
2) Toujours en Java, on peut ajouter des méthodes (polymorphes) aux
enums. Ceci devrait poser questions à ceux qui préconisent des switch...
Pas n'importe quelles méthodes non plus. Tu ne peux pas avoir "d'état"
dans ton enum. Si ton code a besoin d'états, il te faut une classe! En
pratique ce sont des méthodes simple sans effets de bords. Elle
retournent la constante représentant l'enum dans un autre format ou
effectuent des tests (cas exposé dans l'url).
En tout état de cause, je vois que tu te place au niveau conception, et
moi au niveau pratique. Au niveau conception je suis d'accord on peut se
poser la question d'avoir des enum ou des objets en nombres "finis".
Mais une fois ce choix effectué, tu dois faire avec l'existant et
finalement tu utilises les switchs parce que c'est plus pratique qu'un
nombre incessant de if/else/if imbriqué.
Bref, il est des cas où l'enum n'est finalement qu'une valeur
symbolique, et dans ce cas il faut le traiter comme on traite les
constantes entières et donc ils ont toute leur place dans les switch()s.
Tu trouvera quand même qu'il vaut mieux utiliser un Enum qu'une
constante entière dans le code, non ?
A l'inverse il est des cas ou l'on trouve un enum dans les attributs
d'une classe et que beaucoup de méthodes de la classe dépendent de la
valeur de l'enum pour effectuer un traitement différent (en gros l'enum
sert à encoder des sous-classes qui n'ont pas été définies) et là je
suis d'accord qu'il vaut mieux dégager l'attribut Enum et ajouter des
sous-classes pour particulariser les traitements.
Tout dépend de ce qu'on veut faire de l'Enum finalement.
sam.
Wykaaa a écrit :
Tu raisonne par les traitements. En objet on raisonne par les
Ce sont les traitements sur les data qui font le travail et apportent de
la valeur à un soft je pense bien. Il est important que le traitement
soit bien placé dans les choix architecturaux, car si on raisonne sans
se préoccuper des traitements, on a un joli diagramme de classe plein de
joli design patterns mais impraticable par la suite pour ceux qui
doivent tirer parti des data pour faire des traitements efficaces.
> <snip>
Bref: les data se dispersent dans l'arbre d'agrégation et c'est très
bien car elles sont utiles à beaucoup, mais faire la même chose
systématiquement pour le traitement peut être mauvais si la
granularité n'est pas bonne. Ainsi choisir de faire une méthode par
switch est un mauvais choix à mon avis.
Si la méthode en question est utilisée par beaucoup d'objets, c'est
justement ce qu'il faut faire sinon on duplique beaucoup de code !
Ce que je dis c'est que si dans la classe enum les méthodes ne sont
utilisées que par une seule autre classe, c'est qu'alors il y a lieu de
se poser la question de savoir si cette méthode ne devrait pas plutôt
figurer dans la classe qui en a besoin (localiser les traitements).
Un truc simple pour savoir si le découpage est le bon est de regarder
si les méthodes-switch ne sont appelées que depuis un seul point (ce
qui est assez logique vu qu'elles effectue un traitement qui aurait
du être fait par une autre classe). Si c'est le cas, il faudrait voir
si le traitement n'est pas trop spécifique au point d'appel et ne
devrait pas être publié par la classe-enum mais plutôt déplacé à
l'endroit où on en a besoin.
Tu prends le problème à l'envers car on ne part pas du code mais de la
conception !
Quand le code est là (99% des programmes finalement), ou que tu n'es pas
la personne en charge de la conception et ce qu'on te demande c'est de
travailler avec l'existant sans rien casser (la vie de tous les jours
quoi), et bien finalement tu es assez content de pouvoir utiliser l'enum
localement dans un switch plutôt que d'avoir à ajouter une méthode dans
la classe Enum parce que soit tu n'en a pas le droit (politique de
responsabilité: tu sors de ton périmètre), soit tu ne peux pas (pas de
code fourni).
C'est donc en conception qu'on se pose la question de comment
implémenter un enum. Je répète que c'est une abstraction comme une
autre. Donc il faut se poser les questions :
- Est-elle très réutilisée par différentes abstractions ? si oui,
utiliser le pattern Strategy pour implémenter l'enum (donc utiliser
mon point de vue)
- Doit-elle posséder des traitements généraux utiles à tous le monde ?
si oui, implémenter l'enum comme une classe.
- Au contraire est-elle très localisée ? si oui, on peut, peut-être,
utiliser un enum simple et un switch
je rappelle que :
1) les enum polymorphes existent en Java.
Voir : http://langrsoft.com/articles/enum2.shtml
2) Toujours en Java, on peut ajouter des méthodes (polymorphes) aux
enums. Ceci devrait poser questions à ceux qui préconisent des switch...
Pas n'importe quelles méthodes non plus. Tu ne peux pas avoir "d'état"
dans ton enum. Si ton code a besoin d'états, il te faut une classe! En
pratique ce sont des méthodes simple sans effets de bords. Elle
retournent la constante représentant l'enum dans un autre format ou
effectuent des tests (cas exposé dans l'url).
En tout état de cause, je vois que tu te place au niveau conception, et
moi au niveau pratique. Au niveau conception je suis d'accord on peut se
poser la question d'avoir des enum ou des objets en nombres "finis".
Mais une fois ce choix effectué, tu dois faire avec l'existant et
finalement tu utilises les switchs parce que c'est plus pratique qu'un
nombre incessant de if/else/if imbriqué.
Bref, il est des cas où l'enum n'est finalement qu'une valeur
symbolique, et dans ce cas il faut le traiter comme on traite les
constantes entières et donc ils ont toute leur place dans les switch()s.
Tu trouvera quand même qu'il vaut mieux utiliser un Enum qu'une
constante entière dans le code, non ?
A l'inverse il est des cas ou l'on trouve un enum dans les attributs
d'une classe et que beaucoup de méthodes de la classe dépendent de la
valeur de l'enum pour effectuer un traitement différent (en gros l'enum
sert à encoder des sous-classes qui n'ont pas été définies) et là je
suis d'accord qu'il vaut mieux dégager l'attribut Enum et ajouter des
sous-classes pour particulariser les traitements.
Tout dépend de ce qu'on veut faire de l'Enum finalement.
sam.
Wykaaa a écrit :Tu raisonne par les traitements. En objet on raisonne par les
Ce sont les traitements sur les data qui font le travail et apportent de
la valeur à un soft je pense bien. Il est important que le traitement
soit bien placé dans les choix architecturaux, car si on raisonne sans
se préoccuper des traitements, on a un joli diagramme de classe plein de
joli design patterns mais impraticable par la suite pour ceux qui
doivent tirer parti des data pour faire des traitements efficaces.
> <snip>
Bref: les data se dispersent dans l'arbre d'agrégation et c'est très
bien car elles sont utiles à beaucoup, mais faire la même chose
systématiquement pour le traitement peut être mauvais si la
granularité n'est pas bonne. Ainsi choisir de faire une méthode par
switch est un mauvais choix à mon avis.
Si la méthode en question est utilisée par beaucoup d'objets, c'est
justement ce qu'il faut faire sinon on duplique beaucoup de code !
Ce que je dis c'est que si dans la classe enum les méthodes ne sont
utilisées que par une seule autre classe, c'est qu'alors il y a lieu de
se poser la question de savoir si cette méthode ne devrait pas plutôt
figurer dans la classe qui en a besoin (localiser les traitements).
Un truc simple pour savoir si le découpage est le bon est de regarder
si les méthodes-switch ne sont appelées que depuis un seul point (ce
qui est assez logique vu qu'elles effectue un traitement qui aurait
du être fait par une autre classe). Si c'est le cas, il faudrait voir
si le traitement n'est pas trop spécifique au point d'appel et ne
devrait pas être publié par la classe-enum mais plutôt déplacé à
l'endroit où on en a besoin.
Tu prends le problème à l'envers car on ne part pas du code mais de la
conception !
Quand le code est là (99% des programmes finalement), ou que tu n'es pas
la personne en charge de la conception et ce qu'on te demande c'est de
travailler avec l'existant sans rien casser (la vie de tous les jours
quoi), et bien finalement tu es assez content de pouvoir utiliser l'enum
localement dans un switch plutôt que d'avoir à ajouter une méthode dans
la classe Enum parce que soit tu n'en a pas le droit (politique de
responsabilité: tu sors de ton périmètre), soit tu ne peux pas (pas de
code fourni).
C'est donc en conception qu'on se pose la question de comment
implémenter un enum. Je répète que c'est une abstraction comme une
autre. Donc il faut se poser les questions :
- Est-elle très réutilisée par différentes abstractions ? si oui,
utiliser le pattern Strategy pour implémenter l'enum (donc utiliser
mon point de vue)
- Doit-elle posséder des traitements généraux utiles à tous le monde ?
si oui, implémenter l'enum comme une classe.
- Au contraire est-elle très localisée ? si oui, on peut, peut-être,
utiliser un enum simple et un switch
je rappelle que :
1) les enum polymorphes existent en Java.
Voir : http://langrsoft.com/articles/enum2.shtml
2) Toujours en Java, on peut ajouter des méthodes (polymorphes) aux
enums. Ceci devrait poser questions à ceux qui préconisent des switch...
Pas n'importe quelles méthodes non plus. Tu ne peux pas avoir "d'état"
dans ton enum. Si ton code a besoin d'états, il te faut une classe! En
pratique ce sont des méthodes simple sans effets de bords. Elle
retournent la constante représentant l'enum dans un autre format ou
effectuent des tests (cas exposé dans l'url).
En tout état de cause, je vois que tu te place au niveau conception, et
moi au niveau pratique. Au niveau conception je suis d'accord on peut se
poser la question d'avoir des enum ou des objets en nombres "finis".
Mais une fois ce choix effectué, tu dois faire avec l'existant et
finalement tu utilises les switchs parce que c'est plus pratique qu'un
nombre incessant de if/else/if imbriqué.
Bref, il est des cas où l'enum n'est finalement qu'une valeur
symbolique, et dans ce cas il faut le traiter comme on traite les
constantes entières et donc ils ont toute leur place dans les switch()s.
Tu trouvera quand même qu'il vaut mieux utiliser un Enum qu'une
constante entière dans le code, non ?
A l'inverse il est des cas ou l'on trouve un enum dans les attributs
d'une classe et que beaucoup de méthodes de la classe dépendent de la
valeur de l'enum pour effectuer un traitement différent (en gros l'enum
sert à encoder des sous-classes qui n'ont pas été définies) et là je
suis d'accord qu'il vaut mieux dégager l'attribut Enum et ajouter des
sous-classes pour particulariser les traitements.
Tout dépend de ce qu'on veut faire de l'Enum finalement.
sam.
C'est implicite. Tu ferais une interface JourDeLaSemaine avec une
implémentation par jour pour décrire les jours de la semaine ? Non. Donc
c'est typiquement un cas pour lequel l'utilisation des enums est
pertinent.
Et bien je l'ai fait et ça me paraît la façon la plus naturelle car pour
chaque jour de la semaine, il n'y a pas forcément les mêmes activités et
j'utiliserai donc le polymorphisme sur les sous-classes représentant
chaque jour de la semaine pour déclencher des activités (j'aurai une
méthode activerLesActivites() qui déclenchera, suivant le jour
considéré, des activités différentes).
C'est implicite. Tu ferais une interface JourDeLaSemaine avec une
implémentation par jour pour décrire les jours de la semaine ? Non. Donc
c'est typiquement un cas pour lequel l'utilisation des enums est
pertinent.
Et bien je l'ai fait et ça me paraît la façon la plus naturelle car pour
chaque jour de la semaine, il n'y a pas forcément les mêmes activités et
j'utiliserai donc le polymorphisme sur les sous-classes représentant
chaque jour de la semaine pour déclencher des activités (j'aurai une
méthode activerLesActivites() qui déclenchera, suivant le jour
considéré, des activités différentes).
C'est implicite. Tu ferais une interface JourDeLaSemaine avec une
implémentation par jour pour décrire les jours de la semaine ? Non. Donc
c'est typiquement un cas pour lequel l'utilisation des enums est
pertinent.
Et bien je l'ai fait et ça me paraît la façon la plus naturelle car pour
chaque jour de la semaine, il n'y a pas forcément les mêmes activités et
j'utiliserai donc le polymorphisme sur les sous-classes représentant
chaque jour de la semaine pour déclencher des activités (j'aurai une
méthode activerLesActivites() qui déclenchera, suivant le jour
considéré, des activités différentes).
> Par exemple, un code ecrit comme ceci:
SomeClass o;
if(o.getEnum()==Enum.val1) {
// traitement 1
} else {
if(o.getEnum()==Enum.val2) {
// traitement 2
} else {
if(o.getEnum()==Enum.val3) {
// traitement 3
} else {
// comme cela sur 8 ou 9 valeurs
}
}
}
Est me semble-t-il plus lisible avec un
switch(o.getEnum()) {
case Enum.val1:
// traitement1
break;
case Enum.val2:
// traitement2
break
case Enum.val3:
// traitement2
break
}
Sans compter que si on a de traitement identiques pour des valeurs
d'enum le compilo pourra factoriser et re-organiser le code pour nous.
> Par exemple, un code ecrit comme ceci:
SomeClass o;
if(o.getEnum()==Enum.val1) {
// traitement 1
} else {
if(o.getEnum()==Enum.val2) {
// traitement 2
} else {
if(o.getEnum()==Enum.val3) {
// traitement 3
} else {
// comme cela sur 8 ou 9 valeurs
}
}
}
Est me semble-t-il plus lisible avec un
switch(o.getEnum()) {
case Enum.val1:
// traitement1
break;
case Enum.val2:
// traitement2
break
case Enum.val3:
// traitement2
break
}
Sans compter que si on a de traitement identiques pour des valeurs
d'enum le compilo pourra factoriser et re-organiser le code pour nous.
> Par exemple, un code ecrit comme ceci:
SomeClass o;
if(o.getEnum()==Enum.val1) {
// traitement 1
} else {
if(o.getEnum()==Enum.val2) {
// traitement 2
} else {
if(o.getEnum()==Enum.val3) {
// traitement 3
} else {
// comme cela sur 8 ou 9 valeurs
}
}
}
Est me semble-t-il plus lisible avec un
switch(o.getEnum()) {
case Enum.val1:
// traitement1
break;
case Enum.val2:
// traitement2
break
case Enum.val3:
// traitement2
break
}
Sans compter que si on a de traitement identiques pour des valeurs
d'enum le compilo pourra factoriser et re-organiser le code pour nous.