IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Design Patterns Discussion :

Méthode dans la classe Abstraite Component


Sujet :

Design Patterns

  1. #1
    Futur Membre du Club
    Inscrit en
    Août 2009
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 10
    Points : 6
    Points
    6
    Par défaut 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??

  2. #2
    Expert confirmé
    Avatar de Hephaistos007
    Profil pro
    Enseignant Chercheur
    Inscrit en
    Décembre 2004
    Messages
    2 493
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2004
    Messages : 2 493
    Points : 4 166
    Points
    4 166
    Par défaut
    J'ai effectivement déjà vu ce cas de figure avec lequel je suis en total désaccord. Par définition, la classe Leaf n'a pas à posséder les méthodes add et remove. Celui là est correct :


  3. #3
    Futur Membre du Club
    Inscrit en
    Août 2009
    Messages
    10
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 10
    Points : 6
    Points
    6
    Par défaut
    Merci, je suis d'accord avec cette solution

  4. #4
    Expert confirmé

    Homme Profil pro
    SDE
    Inscrit en
    Août 2007
    Messages
    2 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : SDE

    Informations forums :
    Inscription : Août 2007
    Messages : 2 013
    Points : 4 327
    Points
    4 327
    Par défaut
    Citation Envoyé par didine6393 Voir le message
    Merci, je suis d'accord avec cette solution
    Moi je ne suis pas d'accord, même si je suis tout à fait sensible à la contradiction qui se pose ici. En effet il n'y a pas de sens d'avoir des méthodes d'ajout et de supression sur une feuille, mais voici mon point de vue.

    Soit les structures de données suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public interface Composant {
        void add(Composant composant);
        void delete(Composant composant);
        List<Composant> getComposants();
    }
    
    public class Composite extends Composant {
        // Implementation
    }
    
    public class Leaf extends Composant {
        // Implementation
    }
    Lorsque qu'il faudra utiliser notre pattern :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class Main {
        public static void main(String[] argv) {
            List<Composant> composants = new ArrayList<Composant>();
            // Utilisation de la liste.
        }
    }
    Nous sommes d'accord avec le fait que l'interface Composant permet une abstraction qui fait prendre tout son sens à ce pattern. Or ici, si nous voulons ajouter un composant à un autre nous sommes obligé de faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(monComposant instanceof Composant) {
        ((Composite) monComposant).add(nouveauComposant);
    }
    On est obligé de tester le type d'instance, et donc de perdre l'abstraction fondamentale de ce pattern pour pouvoir simplement l'utiliser.

    De plus, ici j'ai donné un exemple en Java, mais dans d'autres langage (comme en C++) il n'y a pas de JVM nous permettant de tester le type d'instance, la tentative du cast peut s'avérrer dramatique pour la robustesse de l'application.

    Pour régler définitivement ce problème, il suffit de soulever une exceptions dans l'implémentation fille. Cette exception peut servir de flag indiquant la fin du parcour sur une certaine branche d'un arbre, et donc non seulement permet de conserver l'abstraction, mais en plus améliore l'utilisabilité du pattern.

    Je tiens à préciser que cet avis n'est pas pas partagé uniquement par moi, mais c'est également l'implémentation conseillé par "the gang of four".

  5. #5
    Membre émérite
    Avatar de SpiceGuid
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    1 704
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 704
    Points : 2 991
    Points
    2 991
    Par défaut 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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

Discussions similaires

  1. Réponses: 5
    Dernier message: 28/11/2014, 15h46
  2. Ajout d'une méthode dans une classe
    Par Flow_75 dans le forum C++
    Réponses: 6
    Dernier message: 12/02/2007, 11h42
  3. [POO] Fonctions dans une classe abstraite
    Par Seth77 dans le forum Langage
    Réponses: 4
    Dernier message: 27/06/2006, 14h21
  4. Réponses: 4
    Dernier message: 25/05/2006, 15h46
  5. Réponses: 2
    Dernier message: 27/03/2005, 17h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo