Marc Espie a écrit :
> Les variables non initialisees (et leur copain, les switch
> sur un champ type) sont des symptomes de design faits par
> des gens qui n'ont pas encore bien integre la conception
> objet (ou qui, pour de basses questions de temps, n'ont pas
> termine leur design).
En approche objet, je n'utilise jamais des enums. Je passe
toujours par l'héritage.
Un enum, c'est une classe abstraite et il y a autant de
sous-classes que de valeurs dans l'enum.
Marc Espie a écrit :
> Les variables non initialisees (et leur copain, les switch
> sur un champ type) sont des symptomes de design faits par
> des gens qui n'ont pas encore bien integre la conception
> objet (ou qui, pour de basses questions de temps, n'ont pas
> termine leur design).
En approche objet, je n'utilise jamais des enums. Je passe
toujours par l'héritage.
Un enum, c'est une classe abstraite et il y a autant de
sous-classes que de valeurs dans l'enum.
Marc Espie a écrit :
> Les variables non initialisees (et leur copain, les switch
> sur un champ type) sont des symptomes de design faits par
> des gens qui n'ont pas encore bien integre la conception
> objet (ou qui, pour de basses questions de temps, n'ont pas
> termine leur design).
En approche objet, je n'utilise jamais des enums. Je passe
toujours par l'héritage.
Un enum, c'est une classe abstraite et il y a autant de
sous-classes que de valeurs dans l'enum.
On 27 jan, 20:45, Wykaaa wrote:En approche objet, je n'utilise jamais des enums. Je passe toujours par
l'héritage.
Un enum, c'est une classe abstraite et il y a autant de sous-classes que
de valeurs dans l'enum.
Faut pas faire dans le dogmatisme.
Il faut utiliser les enums pour ce quoi elle sont utiles;
effectivement, si c'est pour faire un mécanisme de sélection
de type, le polymorphisme est plus adapté.
Mais dans ce cas, tu aurais en dire autant des switches.
J'ai vu beaucoup de projets où l'héritage était utilisé à outrance,
où tout était modélisé en classes :
ces programmes étaient difficiles à comprendre et à maintenir.
On 27 jan, 20:45, Wykaaa <wyk...@yahoo.fr> wrote:
En approche objet, je n'utilise jamais des enums. Je passe toujours par
l'héritage.
Un enum, c'est une classe abstraite et il y a autant de sous-classes que
de valeurs dans l'enum.
Faut pas faire dans le dogmatisme.
Il faut utiliser les enums pour ce quoi elle sont utiles;
effectivement, si c'est pour faire un mécanisme de sélection
de type, le polymorphisme est plus adapté.
Mais dans ce cas, tu aurais en dire autant des switches.
J'ai vu beaucoup de projets où l'héritage était utilisé à outrance,
où tout était modélisé en classes :
ces programmes étaient difficiles à comprendre et à maintenir.
On 27 jan, 20:45, Wykaaa wrote:En approche objet, je n'utilise jamais des enums. Je passe toujours par
l'héritage.
Un enum, c'est une classe abstraite et il y a autant de sous-classes que
de valeurs dans l'enum.
Faut pas faire dans le dogmatisme.
Il faut utiliser les enums pour ce quoi elle sont utiles;
effectivement, si c'est pour faire un mécanisme de sélection
de type, le polymorphisme est plus adapté.
Mais dans ce cas, tu aurais en dire autant des switches.
J'ai vu beaucoup de projets où l'héritage était utilisé à outrance,
où tout était modélisé en classes :
ces programmes étaient difficiles à comprendre et à maintenir.
On Jan 27, 7:45 pm, Wykaaa wrote:Marc Espie a écrit :
[...]Les variables non initialisees (et leur copain, les switch
sur un champ type) sont des symptomes de design faits par
des gens qui n'ont pas encore bien integre la conception
objet (ou qui, pour de basses questions de temps, n'ont pas
termine leur design).En approche objet, je n'utilise jamais des enums. Je passe
toujours par l'héritage.
Étant donné que les deux sert à des buts complètement
différents, je ne vois pas le rapport. J'en utilise les deux.
Un enum, c'est une classe abstraite et il y a autant de
sous-classes que de valeurs dans l'enum.
Sauf qu'un enum, ça n'a rien à voir avec une classe, abstraite
ou non. (Pour commencer, un enum, c'est une valeur, et une
classe abstraite suppose en général un comportement et une
identité. Tout à fait l'opposer d'un enum.)
On Jan 27, 7:45 pm, Wykaaa <wyk...@yahoo.fr> wrote:
Marc Espie a écrit :
[...]
Les variables non initialisees (et leur copain, les switch
sur un champ type) sont des symptomes de design faits par
des gens qui n'ont pas encore bien integre la conception
objet (ou qui, pour de basses questions de temps, n'ont pas
termine leur design).
En approche objet, je n'utilise jamais des enums. Je passe
toujours par l'héritage.
Étant donné que les deux sert à des buts complètement
différents, je ne vois pas le rapport. J'en utilise les deux.
Un enum, c'est une classe abstraite et il y a autant de
sous-classes que de valeurs dans l'enum.
Sauf qu'un enum, ça n'a rien à voir avec une classe, abstraite
ou non. (Pour commencer, un enum, c'est une valeur, et une
classe abstraite suppose en général un comportement et une
identité. Tout à fait l'opposer d'un enum.)
On Jan 27, 7:45 pm, Wykaaa wrote:Marc Espie a écrit :
[...]Les variables non initialisees (et leur copain, les switch
sur un champ type) sont des symptomes de design faits par
des gens qui n'ont pas encore bien integre la conception
objet (ou qui, pour de basses questions de temps, n'ont pas
termine leur design).En approche objet, je n'utilise jamais des enums. Je passe
toujours par l'héritage.
Étant donné que les deux sert à des buts complètement
différents, je ne vois pas le rapport. J'en utilise les deux.
Un enum, c'est une classe abstraite et il y a autant de
sous-classes que de valeurs dans l'enum.
Sauf qu'un enum, ça n'a rien à voir avec une classe, abstraite
ou non. (Pour commencer, un enum, c'est une valeur, et une
classe abstraite suppose en général un comportement et une
identité. Tout à fait l'opposer d'un enum.)
Quel est le plus évolutif ?
Où est ta différence valeur/comportement ?
Quel est le plus évolutif ?
Où est ta différence valeur/comportement ?
Quel est le plus évolutif ?
Où est ta différence valeur/comportement ?
On 28 jan, 00:09, Wykaaa wrote:
[...]Quel est le plus évolutif ?
Où est ta différence valeur/comportement ?
Même avec une conception objet du logiciel efficace,
à un moment donné, il te faudra bien implémenter
*un peu* d'algorithmie.
Et là, tu peux dire ce que tu veux, pour être efficace
(en rapidité, lisibilité et maintenance),
les enum, switch ou if/else sont tout adaptés.
Lorsque c'est bien, conçu, ce ne pose aucun pb
( à l'echelle de l'algo évidemment).
On 28 jan, 00:09, Wykaaa <wyk...@yahoo.fr> wrote:
[...]
Quel est le plus évolutif ?
Où est ta différence valeur/comportement ?
Même avec une conception objet du logiciel efficace,
à un moment donné, il te faudra bien implémenter
*un peu* d'algorithmie.
Et là, tu peux dire ce que tu veux, pour être efficace
(en rapidité, lisibilité et maintenance),
les enum, switch ou if/else sont tout adaptés.
Lorsque c'est bien, conçu, ce ne pose aucun pb
( à l'echelle de l'algo évidemment).
On 28 jan, 00:09, Wykaaa wrote:
[...]Quel est le plus évolutif ?
Où est ta différence valeur/comportement ?
Même avec une conception objet du logiciel efficace,
à un moment donné, il te faudra bien implémenter
*un peu* d'algorithmie.
Et là, tu peux dire ce que tu veux, pour être efficace
(en rapidité, lisibilité et maintenance),
les enum, switch ou if/else sont tout adaptés.
Lorsque c'est bien, conçu, ce ne pose aucun pb
( à l'echelle de l'algo évidemment).
Mon exemple ne te parle-t-il pas ?
Jour j = new ...;
Les switches sont une horreur pour la maintenance et les évolutions
quand on fait de l'objet alors que le polymorphisme rend les
"aiguillages" automatiques quand on ajoute des sous-classes.
Mon exemple ne te parle-t-il pas ?
Jour j = new ...;
Les switches sont une horreur pour la maintenance et les évolutions
quand on fait de l'objet alors que le polymorphisme rend les
"aiguillages" automatiques quand on ajoute des sous-classes.
Mon exemple ne te parle-t-il pas ?
Jour j = new ...;
Les switches sont une horreur pour la maintenance et les évolutions
quand on fait de l'objet alors que le polymorphisme rend les
"aiguillages" automatiques quand on ajoute des sous-classes.
James Kanze a écrit :
> On Jan 27, 7:45 pm, Wykaaa wrote:
>> Marc Espie a écrit :
> [...]
>>> Les variables non initialisees (et leur copain, les switch
>>> sur un champ type) sont des symptomes de design faits par
>>> des gens qui n'ont pas encore bien integre la conception
>>> objet (ou qui, pour de basses questions de temps, n'ont pas
>>> termine leur design).
>> En approche objet, je n'utilise jamais des enums. Je passe
>> toujours par l'héritage.
> Étant donné que les deux sert à des buts complètement
> différents, je ne vois pas le rapport. J'en utilise les deux.
Non, il n'ont pas des buts différents.
>> Un enum, c'est une classe abstraite et il y a autant de
>> sous-classes que de valeurs dans l'enum.
> Sauf qu'un enum, ça n'a rien à voir avec une classe, abstraite
> ou non. (Pour commencer, un enum, c'est une valeur, et une
> classe abstraite suppose en général un comportement et une
> identité. Tout à fait l'opposer d'un enum.)
Tu veux dire qu'un enum est une variable scalaire quand tu dis "valeur"?
Et un enum, ça a un comportement puisqu'on le gère avec des switches. ..
1) enum
enum Jour {LUNDI, MARDI, MERCREDI, ...};
Jour j = ...;
void travailler(Jour leJour)
{
switch(j)
{
case LUNDI : //faire ceci
case MARDI : //faire cela
case MERCREDI : //faire autre chose
...
}
travailler(j);
N'est-ce pas une fonction qui décrit un comportement de l'enum ?
2) polymorphisme
class Jour
{
public:
virtual void travailler()=0;
// éventuellement d'autres méthodes
}
class Lundi
{
public:
virtual void travailler() {//faire ceci}};
class Mardi
{
public:
virtual void travailler() {//faire cela}};
class Mercredi
{
public:
virtual void travailler() {//faire autre chose}
}
Jour j = new ...;
j.travailler();
Quel est le plus évolutif ?
Où est ta différence valeur/comportement ?
Et encore, j'ai pris un exemple ou il n'y aura pas de nouvelle valeur
pour l'enum mais si c'était le cas, quel est le plus simple à mainten ir,
et même à comprendre sachant que si j'ai plusieurs méthodes sur Jour,
les switches seront éventuellement disséminés partout dans le code alors
que là, l'arborescence de Jour sera dans le module Jour.h/Jour.cpp
(forte cohésion)
C'est pareil pour les pièces de l'échiquier et Move devient une mét hode
virtuelle de Pièce.
La promotion c'est la destruction de la pièce, objet de la promotion, e t
la création, avec la même position (que je préfère à l'identifi ant
"coordonnées") de la pièce qui la remplace.
Position est d'ailleurs elle-même une classe.
Si cela pose des problèmes de performances, alors il ne faut pas
utiliser C++ mais C, par exemple, avec force enums et switches mais ça
va être non maintenable. Cependant on sait que si c'est la performance
qui prime sur tous les autres facteurs, le code résultant n'est, en
général, plus maintenable.
James Kanze a écrit :
> On Jan 27, 7:45 pm, Wykaaa <wyk...@yahoo.fr> wrote:
>> Marc Espie a écrit :
> [...]
>>> Les variables non initialisees (et leur copain, les switch
>>> sur un champ type) sont des symptomes de design faits par
>>> des gens qui n'ont pas encore bien integre la conception
>>> objet (ou qui, pour de basses questions de temps, n'ont pas
>>> termine leur design).
>> En approche objet, je n'utilise jamais des enums. Je passe
>> toujours par l'héritage.
> Étant donné que les deux sert à des buts complètement
> différents, je ne vois pas le rapport. J'en utilise les deux.
Non, il n'ont pas des buts différents.
>> Un enum, c'est une classe abstraite et il y a autant de
>> sous-classes que de valeurs dans l'enum.
> Sauf qu'un enum, ça n'a rien à voir avec une classe, abstraite
> ou non. (Pour commencer, un enum, c'est une valeur, et une
> classe abstraite suppose en général un comportement et une
> identité. Tout à fait l'opposer d'un enum.)
Tu veux dire qu'un enum est une variable scalaire quand tu dis "valeur"?
Et un enum, ça a un comportement puisqu'on le gère avec des switches. ..
1) enum
enum Jour {LUNDI, MARDI, MERCREDI, ...};
Jour j = ...;
void travailler(Jour leJour)
{
switch(j)
{
case LUNDI : //faire ceci
case MARDI : //faire cela
case MERCREDI : //faire autre chose
...
}
travailler(j);
N'est-ce pas une fonction qui décrit un comportement de l'enum ?
2) polymorphisme
class Jour
{
public:
virtual void travailler()=0;
// éventuellement d'autres méthodes
}
class Lundi
{
public:
virtual void travailler() {//faire ceci}};
class Mardi
{
public:
virtual void travailler() {//faire cela}};
class Mercredi
{
public:
virtual void travailler() {//faire autre chose}
}
Jour j = new ...;
j.travailler();
Quel est le plus évolutif ?
Où est ta différence valeur/comportement ?
Et encore, j'ai pris un exemple ou il n'y aura pas de nouvelle valeur
pour l'enum mais si c'était le cas, quel est le plus simple à mainten ir,
et même à comprendre sachant que si j'ai plusieurs méthodes sur Jour,
les switches seront éventuellement disséminés partout dans le code alors
que là, l'arborescence de Jour sera dans le module Jour.h/Jour.cpp
(forte cohésion)
C'est pareil pour les pièces de l'échiquier et Move devient une mét hode
virtuelle de Pièce.
La promotion c'est la destruction de la pièce, objet de la promotion, e t
la création, avec la même position (que je préfère à l'identifi ant
"coordonnées") de la pièce qui la remplace.
Position est d'ailleurs elle-même une classe.
Si cela pose des problèmes de performances, alors il ne faut pas
utiliser C++ mais C, par exemple, avec force enums et switches mais ça
va être non maintenable. Cependant on sait que si c'est la performance
qui prime sur tous les autres facteurs, le code résultant n'est, en
général, plus maintenable.
James Kanze a écrit :
> On Jan 27, 7:45 pm, Wykaaa wrote:
>> Marc Espie a écrit :
> [...]
>>> Les variables non initialisees (et leur copain, les switch
>>> sur un champ type) sont des symptomes de design faits par
>>> des gens qui n'ont pas encore bien integre la conception
>>> objet (ou qui, pour de basses questions de temps, n'ont pas
>>> termine leur design).
>> En approche objet, je n'utilise jamais des enums. Je passe
>> toujours par l'héritage.
> Étant donné que les deux sert à des buts complètement
> différents, je ne vois pas le rapport. J'en utilise les deux.
Non, il n'ont pas des buts différents.
>> Un enum, c'est une classe abstraite et il y a autant de
>> sous-classes que de valeurs dans l'enum.
> Sauf qu'un enum, ça n'a rien à voir avec une classe, abstraite
> ou non. (Pour commencer, un enum, c'est une valeur, et une
> classe abstraite suppose en général un comportement et une
> identité. Tout à fait l'opposer d'un enum.)
Tu veux dire qu'un enum est une variable scalaire quand tu dis "valeur"?
Et un enum, ça a un comportement puisqu'on le gère avec des switches. ..
1) enum
enum Jour {LUNDI, MARDI, MERCREDI, ...};
Jour j = ...;
void travailler(Jour leJour)
{
switch(j)
{
case LUNDI : //faire ceci
case MARDI : //faire cela
case MERCREDI : //faire autre chose
...
}
travailler(j);
N'est-ce pas une fonction qui décrit un comportement de l'enum ?
2) polymorphisme
class Jour
{
public:
virtual void travailler()=0;
// éventuellement d'autres méthodes
}
class Lundi
{
public:
virtual void travailler() {//faire ceci}};
class Mardi
{
public:
virtual void travailler() {//faire cela}};
class Mercredi
{
public:
virtual void travailler() {//faire autre chose}
}
Jour j = new ...;
j.travailler();
Quel est le plus évolutif ?
Où est ta différence valeur/comportement ?
Et encore, j'ai pris un exemple ou il n'y aura pas de nouvelle valeur
pour l'enum mais si c'était le cas, quel est le plus simple à mainten ir,
et même à comprendre sachant que si j'ai plusieurs méthodes sur Jour,
les switches seront éventuellement disséminés partout dans le code alors
que là, l'arborescence de Jour sera dans le module Jour.h/Jour.cpp
(forte cohésion)
C'est pareil pour les pièces de l'échiquier et Move devient une mét hode
virtuelle de Pièce.
La promotion c'est la destruction de la pièce, objet de la promotion, e t
la création, avec la même position (que je préfère à l'identifi ant
"coordonnées") de la pièce qui la remplace.
Position est d'ailleurs elle-même une classe.
Si cela pose des problèmes de performances, alors il ne faut pas
utiliser C++ mais C, par exemple, avec force enums et switches mais ça
va être non maintenable. Cependant on sait que si c'est la performance
qui prime sur tous les autres facteurs, le code résultant n'est, en
général, plus maintenable.
Dans le cas de l'échequier je ne suis pas sûr que la modélisation des
pièces soit un point central. Une recherche se fera plutôt sur l'état
d'un plateau, les pièces existeront en instance unique pour générer
les états de plateau suivant.
Dans le cas de l'échequier je ne suis pas sûr que la modélisation des
pièces soit un point central. Une recherche se fera plutôt sur l'état
d'un plateau, les pièces existeront en instance unique pour générer
les états de plateau suivant.
Dans le cas de l'échequier je ne suis pas sûr que la modélisation des
pièces soit un point central. Une recherche se fera plutôt sur l'état
d'un plateau, les pièces existeront en instance unique pour générer
les états de plateau suivant.
On 28 jan, 12:53, Wykaaa wrote:Mon exemple ne te parle-t-il pas ?
Non car tu as omis le plus important :Jour j = new ...;
Comment détermines-tu le type à instancier ?
Les switches sont une horreur pour la maintenance et les évolutions
quand on fait de l'objet alors que le polymorphisme rend les
"aiguillages" automatiques quand on ajoute des sous-classes.
Et d'autre part, tu mets quoi dans tes pattern factory ?
On 28 jan, 12:53, Wykaaa <wyk...@yahoo.fr> wrote:
Mon exemple ne te parle-t-il pas ?
Non car tu as omis le plus important :
Jour j = new ...;
Comment détermines-tu le type à instancier ?
Les switches sont une horreur pour la maintenance et les évolutions
quand on fait de l'objet alors que le polymorphisme rend les
"aiguillages" automatiques quand on ajoute des sous-classes.
Et d'autre part, tu mets quoi dans tes pattern factory ?
On 28 jan, 12:53, Wykaaa wrote:Mon exemple ne te parle-t-il pas ?
Non car tu as omis le plus important :Jour j = new ...;
Comment détermines-tu le type à instancier ?
Les switches sont une horreur pour la maintenance et les évolutions
quand on fait de l'objet alors que le polymorphisme rend les
"aiguillages" automatiques quand on ajoute des sous-classes.
Et d'autre part, tu mets quoi dans tes pattern factory ?
On 28 jan, 00:09, Wykaaa wrote:James Kanze a écrit :On Jan 27, 7:45 pm, Wykaaa wrote:Marc Espie a écrit :
[...]Les variables non initialisees (et leur copain, les switch
sur un champ type) sont des symptomes de design faits par
des gens qui n'ont pas encore bien integre la conception
objet (ou qui, pour de basses questions de temps, n'ont pas
termine leur design).
En approche objet, je n'utilise jamais des enums. Je passe
toujours par l'héritage.
Étant donné que les deux sert à des buts complètement
différents, je ne vois pas le rapport. J'en utilise les deux.
Non, il n'ont pas des buts différents.
Formellement, un enum est un type distinct constitué d'un ensemble de
constantes.
C'est l'utilisation que tu en fais qui a un but similaire.
Plus généralement, ilms sont utilisés pour nommer une valeur; c'est
mieux qu'un define car ils ont une portée et à la préférence d'une
static de classe comme ça, il n'a pas besoin d'être défini (sauf quand
des petits malins essayent de faire des enum sur une representation
plus large que int).
Un enum, c'est une classe abstraite et il y a autant de
sous-classes que de valeurs dans l'enum.
Sauf qu'un enum, ça n'a rien à voir avec une classe, abstraite
ou non. (Pour commencer, un enum, c'est une valeur, et une
classe abstraite suppose en général un comportement et une
identité. Tout à fait l'opposer d'un enum.)
Tu veux dire qu'un enum est une variable scalaire quand tu dis "valeur"?
Qui a la propriété interressant qu'à la déclaration, la valeur d'un
enum est la valeur de l'enum précédent + 1.
Et un enum, ça a un comportement puisqu'on le gère avec des switches...
1) enum
enum Jour {LUNDI, MARDI, MERCREDI, ...};
Jour j = ...;
void travailler(Jour leJour)
{
switch(j)
{
case LUNDI : //faire ceci
case MARDI : //faire cela
case MERCREDI : //faire autre chose
...
}
travailler(j);
N'est-ce pas une fonction qui décrit un comportement de l'enum ?
2) polymorphisme
class Jour
{
public:
virtual void travailler()=0;
// éventuellement d'autres méthodes
}
class Lundi
{
public:
virtual void travailler() {//faire ceci}};
class Mardi
{
public:
virtual void travailler() {//faire cela}};
class Mercredi
{
public:
virtual void travailler() {//faire autre chose}
}
Jour j = new ...;
j.travailler();
Quel est le plus évolutif ?
Où est ta différence valeur/comportement ?
La différence est que tu lies une notion d'identification (dans un
set) avec une notion d'execution associée.
En terme d'impact, ça veux dire que le jour ou l'interface travailler
() n'est plus nécessaire (c'est pas demain la veille) ou doit évoluer,
le code deviens énorme.
Alors que l'interface suivante décorelle les deux:
struct IJourDeTravail
{
virtual void travailler()=0;
// éventuellement d'autres méthodes
}
template<Jour J>
struct JourDeTravail;
template<>
struct JourDeTravail<Lundi>
{
virtual void travailler()
{
// ....
}
};
// même code
IJourDeTravaille j = new ...;
j.travailler();
Et encore, j'ai pris un exemple ou il n'y aura pas de nouvelle valeur
pour l'enum mais si c'était le cas, quel est le plus simple à maintenir,
et même à comprendre sachant que si j'ai plusieurs méthodes sur Jour,
les switches seront éventuellement disséminés partout dans le code alors
que là, l'arborescence de Jour sera dans le module Jour.h/Jour.cpp
(forte cohésion)
C'est pareil pour les pièces de l'échiquier et Move devient une méthode
virtuelle de Pièce.
La promotion c'est la destruction de la pièce, objet de la promotion, et
la création, avec la même position (que je préfère à l'identifiant
"coordonnées") de la pièce qui la remplace.
Position est d'ailleurs elle-même une classe.
Dans le cas de l'échequier je ne suis pas sûr que la modélisation des
pièces soit un point central. Une recherche se fera plutôt sur l'état
d'un plateau, les pièces existeront en instance unique pour générer
les états de plateau suivant.
Suivant un tradeoff mémoire/cpu, le plateau sera composé de pointeurs
sur les pièces ou un tableau de char identifiant la pièce à une
position (donc un switch case).
Si cela pose des problèmes de performances, alors il ne faut pas
utiliser C++ mais C, par exemple, avec force enums et switches mais ça
va être non maintenable. Cependant on sait que si c'est la performance
qui prime sur tous les autres facteurs, le code résultant n'est, en
général, plus maintenable.
Et peut être aussi pas plus rapide.
On 28 jan, 00:09, Wykaaa <wyk...@yahoo.fr> wrote:
James Kanze a écrit :
On Jan 27, 7:45 pm, Wykaaa <wyk...@yahoo.fr> wrote:
Marc Espie a écrit :
[...]
Les variables non initialisees (et leur copain, les switch
sur un champ type) sont des symptomes de design faits par
des gens qui n'ont pas encore bien integre la conception
objet (ou qui, pour de basses questions de temps, n'ont pas
termine leur design).
En approche objet, je n'utilise jamais des enums. Je passe
toujours par l'héritage.
Étant donné que les deux sert à des buts complètement
différents, je ne vois pas le rapport. J'en utilise les deux.
Non, il n'ont pas des buts différents.
Formellement, un enum est un type distinct constitué d'un ensemble de
constantes.
C'est l'utilisation que tu en fais qui a un but similaire.
Plus généralement, ilms sont utilisés pour nommer une valeur; c'est
mieux qu'un define car ils ont une portée et à la préférence d'une
static de classe comme ça, il n'a pas besoin d'être défini (sauf quand
des petits malins essayent de faire des enum sur une representation
plus large que int).
Un enum, c'est une classe abstraite et il y a autant de
sous-classes que de valeurs dans l'enum.
Sauf qu'un enum, ça n'a rien à voir avec une classe, abstraite
ou non. (Pour commencer, un enum, c'est une valeur, et une
classe abstraite suppose en général un comportement et une
identité. Tout à fait l'opposer d'un enum.)
Tu veux dire qu'un enum est une variable scalaire quand tu dis "valeur"?
Qui a la propriété interressant qu'à la déclaration, la valeur d'un
enum est la valeur de l'enum précédent + 1.
Et un enum, ça a un comportement puisqu'on le gère avec des switches...
1) enum
enum Jour {LUNDI, MARDI, MERCREDI, ...};
Jour j = ...;
void travailler(Jour leJour)
{
switch(j)
{
case LUNDI : //faire ceci
case MARDI : //faire cela
case MERCREDI : //faire autre chose
...
}
travailler(j);
N'est-ce pas une fonction qui décrit un comportement de l'enum ?
2) polymorphisme
class Jour
{
public:
virtual void travailler()=0;
// éventuellement d'autres méthodes
}
class Lundi
{
public:
virtual void travailler() {//faire ceci}};
class Mardi
{
public:
virtual void travailler() {//faire cela}};
class Mercredi
{
public:
virtual void travailler() {//faire autre chose}
}
Jour j = new ...;
j.travailler();
Quel est le plus évolutif ?
Où est ta différence valeur/comportement ?
La différence est que tu lies une notion d'identification (dans un
set) avec une notion d'execution associée.
En terme d'impact, ça veux dire que le jour ou l'interface travailler
() n'est plus nécessaire (c'est pas demain la veille) ou doit évoluer,
le code deviens énorme.
Alors que l'interface suivante décorelle les deux:
struct IJourDeTravail
{
virtual void travailler()=0;
// éventuellement d'autres méthodes
}
template<Jour J>
struct JourDeTravail;
template<>
struct JourDeTravail<Lundi>
{
virtual void travailler()
{
// ....
}
};
// même code
IJourDeTravaille j = new ...;
j.travailler();
Et encore, j'ai pris un exemple ou il n'y aura pas de nouvelle valeur
pour l'enum mais si c'était le cas, quel est le plus simple à maintenir,
et même à comprendre sachant que si j'ai plusieurs méthodes sur Jour,
les switches seront éventuellement disséminés partout dans le code alors
que là, l'arborescence de Jour sera dans le module Jour.h/Jour.cpp
(forte cohésion)
C'est pareil pour les pièces de l'échiquier et Move devient une méthode
virtuelle de Pièce.
La promotion c'est la destruction de la pièce, objet de la promotion, et
la création, avec la même position (que je préfère à l'identifiant
"coordonnées") de la pièce qui la remplace.
Position est d'ailleurs elle-même une classe.
Dans le cas de l'échequier je ne suis pas sûr que la modélisation des
pièces soit un point central. Une recherche se fera plutôt sur l'état
d'un plateau, les pièces existeront en instance unique pour générer
les états de plateau suivant.
Suivant un tradeoff mémoire/cpu, le plateau sera composé de pointeurs
sur les pièces ou un tableau de char identifiant la pièce à une
position (donc un switch case).
Si cela pose des problèmes de performances, alors il ne faut pas
utiliser C++ mais C, par exemple, avec force enums et switches mais ça
va être non maintenable. Cependant on sait que si c'est la performance
qui prime sur tous les autres facteurs, le code résultant n'est, en
général, plus maintenable.
Et peut être aussi pas plus rapide.
On 28 jan, 00:09, Wykaaa wrote:James Kanze a écrit :On Jan 27, 7:45 pm, Wykaaa wrote:Marc Espie a écrit :
[...]Les variables non initialisees (et leur copain, les switch
sur un champ type) sont des symptomes de design faits par
des gens qui n'ont pas encore bien integre la conception
objet (ou qui, pour de basses questions de temps, n'ont pas
termine leur design).
En approche objet, je n'utilise jamais des enums. Je passe
toujours par l'héritage.
Étant donné que les deux sert à des buts complètement
différents, je ne vois pas le rapport. J'en utilise les deux.
Non, il n'ont pas des buts différents.
Formellement, un enum est un type distinct constitué d'un ensemble de
constantes.
C'est l'utilisation que tu en fais qui a un but similaire.
Plus généralement, ilms sont utilisés pour nommer une valeur; c'est
mieux qu'un define car ils ont une portée et à la préférence d'une
static de classe comme ça, il n'a pas besoin d'être défini (sauf quand
des petits malins essayent de faire des enum sur une representation
plus large que int).
Un enum, c'est une classe abstraite et il y a autant de
sous-classes que de valeurs dans l'enum.
Sauf qu'un enum, ça n'a rien à voir avec une classe, abstraite
ou non. (Pour commencer, un enum, c'est une valeur, et une
classe abstraite suppose en général un comportement et une
identité. Tout à fait l'opposer d'un enum.)
Tu veux dire qu'un enum est une variable scalaire quand tu dis "valeur"?
Qui a la propriété interressant qu'à la déclaration, la valeur d'un
enum est la valeur de l'enum précédent + 1.
Et un enum, ça a un comportement puisqu'on le gère avec des switches...
1) enum
enum Jour {LUNDI, MARDI, MERCREDI, ...};
Jour j = ...;
void travailler(Jour leJour)
{
switch(j)
{
case LUNDI : //faire ceci
case MARDI : //faire cela
case MERCREDI : //faire autre chose
...
}
travailler(j);
N'est-ce pas une fonction qui décrit un comportement de l'enum ?
2) polymorphisme
class Jour
{
public:
virtual void travailler()=0;
// éventuellement d'autres méthodes
}
class Lundi
{
public:
virtual void travailler() {//faire ceci}};
class Mardi
{
public:
virtual void travailler() {//faire cela}};
class Mercredi
{
public:
virtual void travailler() {//faire autre chose}
}
Jour j = new ...;
j.travailler();
Quel est le plus évolutif ?
Où est ta différence valeur/comportement ?
La différence est que tu lies une notion d'identification (dans un
set) avec une notion d'execution associée.
En terme d'impact, ça veux dire que le jour ou l'interface travailler
() n'est plus nécessaire (c'est pas demain la veille) ou doit évoluer,
le code deviens énorme.
Alors que l'interface suivante décorelle les deux:
struct IJourDeTravail
{
virtual void travailler()=0;
// éventuellement d'autres méthodes
}
template<Jour J>
struct JourDeTravail;
template<>
struct JourDeTravail<Lundi>
{
virtual void travailler()
{
// ....
}
};
// même code
IJourDeTravaille j = new ...;
j.travailler();
Et encore, j'ai pris un exemple ou il n'y aura pas de nouvelle valeur
pour l'enum mais si c'était le cas, quel est le plus simple à maintenir,
et même à comprendre sachant que si j'ai plusieurs méthodes sur Jour,
les switches seront éventuellement disséminés partout dans le code alors
que là, l'arborescence de Jour sera dans le module Jour.h/Jour.cpp
(forte cohésion)
C'est pareil pour les pièces de l'échiquier et Move devient une méthode
virtuelle de Pièce.
La promotion c'est la destruction de la pièce, objet de la promotion, et
la création, avec la même position (que je préfère à l'identifiant
"coordonnées") de la pièce qui la remplace.
Position est d'ailleurs elle-même une classe.
Dans le cas de l'échequier je ne suis pas sûr que la modélisation des
pièces soit un point central. Une recherche se fera plutôt sur l'état
d'un plateau, les pièces existeront en instance unique pour générer
les états de plateau suivant.
Suivant un tradeoff mémoire/cpu, le plateau sera composé de pointeurs
sur les pièces ou un tableau de char identifiant la pièce à une
position (donc un switch case).
Si cela pose des problèmes de performances, alors il ne faut pas
utiliser C++ mais C, par exemple, avec force enums et switches mais ça
va être non maintenable. Cependant on sait que si c'est la performance
qui prime sur tous les autres facteurs, le code résultant n'est, en
général, plus maintenable.
Et peut être aussi pas plus rapide.