Méthode dans la classe Abstraite Component
Dans la classe Component, des méthodes abstraites sont définies (add, remove etc...) mais non redéfinies dans la classe fille Leaf, est ce normal ?
D'autres part, s'il faut les redéfinir (ce qui serait logique vu que la classe mére est abstraite), je pense que cela n'a aucun sens pour une feuille de pouvoir ajouter des enfants!!!
Quel est votre avis??
Classes-types vs. types union
C'est deux questions en une :
- quelle est la méthodologie à préconiser ?
- pourquoi c'est mal typé ?
Quelle est la méthodologie à préconiser ?
Le "the gang of four" met explicitement en avant l'interface Composant riche, dans le cas contraire:
- l'interface de Composant est vide puisque l'énumération les enfants n'a de sens qu'au niveau d'un composite
- on peut ajouter une méthode est_feuille dans l'interface de Composant mais ça ne changera pas l'obligation de faire du transtypage
Pourquoi c'est mal typé ?
C'est mal typé parce que ça n'est pas le bon type.
On a pas ce problème avec le pattern interpréteur.
La différence entre les deux c'est que :
- conceptuellement l'interpréteur est un type ouvert (extensible) , ça correspond bien à ce qu'est une classe en POO, on a une classe expression avec une méthode évaluer qu'on peut étendre avec autant de nouvelles expressions toutes évaluables.
- conceptuellement le composite est un type arbre, avec des feuilles et de noeuds. c'est un type fermé (pas extensible), il n'y a pas d'extension possible, les différentes composites ne sont que des éléments pour décorer les noeuds. le nombre d'alternatives est très limité (feuille ou noeud) mais il faut pouvoir les distinguer, c'est le contraire du polymorphisme (le nombre d'alternatives n'est pas limité et on ne veut pas les distinguer). la POO n'offre pas ce genre de types (qui correspond au type union en C).
Une solution proposée par les langages fonctionnels (Scala,F#) consiste à offrir un type union. Mais on change de paradigme et de système de typage.
Une autre solution moins radicale consiste à ajouter une instruction when :
Code:
1 2 3
| when monComposant instanceof Composite {
monComposant.add(nouveauComposant);
} |
when se comporte comme if sauf que si le test réussi alors monComposant devient de type Composite dans toute la portée du bloc.
Problème avec le when :
- monComposant devient de type Composite c'est exactement ce que l'on veut pour accéder à ses enfants
- monComposant devient de type Composite c'est exactement ce que l'on ne veut surtout pas lorsqu'on veut changer la valeur de monComposant
- il peut arriver qu'on veuille, dans le même bloc, accéder aux enfants de monComposant puis le réaffecter à monElement, dans ce cas on ne peut pas utiliser when