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 :

[Java] Quel modele de conception choisir au lieu de l'heritage ? [Décorateur]


Sujet :

Design Patterns

  1. #1
    Membre averti
    Inscrit en
    Mai 2003
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 62
    Par défaut [Java] Quel modele de conception choisir au lieu de l'heritage ?
    Voici un probleme qui m'a ete soumis recemment. Je chercher la meilleure solution possible.

    Soit une classe Voiture dont voici la description :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public classe Voiture {
      private String modele;
    
      private Voiture(String modele) {
        this.modele = modele
      }
    
      public String getModele() {
        return modele;
      }
      
      public double getPrixHT() {
        double prixHT;
    
        // le prix est recupere dans une base de donnees distante.
    
        ...
    
        return prixHT;
      }
    }
    Voila le probleme :

    Une voiture peut etre achetee avec sans options supplementaire. Chaque option s'ajoute au prix de base.

    Voici les options :
    - Traitement anti corrosion : + 8% du prix de base.
    - Boite automatique : + 500 Euros.

    Donc il est possible d'acheter une voiture avec toutes les combinaisons d'option possible ou meme sans option.

    Avez vous une piste a me proposer pour calculer le prix de la voiture avec ou sans options.

    J'ai d'abord pense a l'heritage mais ce n'est pas recommande car toutes les options sont multiples et elles generent beaucoup de combinaisons.

  2. #2
    Expert confirmé
    Avatar de Baptiste Wicht
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    7 431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2005
    Messages : 7 431
    Par défaut
    Je suis pas sûr de vraiment comprendre ton problème...

    Il ne suffirait pas d'avoir une liste d'options dans la classe Voiture et pour le calcule, il suffit de parcourir la liste et d'appeller par exemple la méthode calcul qui renvoie un prix supplémentaire de chaque option. ???

  3. #3
    Membre averti
    Inscrit en
    Mai 2003
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 62
    Par défaut
    Merci pour ta premiere reponse.

    Au debut je voulais creer autant de classes qui heritent de la classe Voiture pour chaque combinaison. J'ajouterais une classe abstraite calculerPrix dans la classe voiture et donc le calcul prendrait en compte le calcul de l'option.

    Mais cela va me faire beaucoup de classe a ecrire si d'autres options se creent.

  4. #4
    Membre émérite
    Avatar de sironimo
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mai 2004
    Messages : 669
    Par défaut
    Attention, tu confonds méthode et classe là je trouve.

    CalculePrix() pourrait être une méthode abstraite à la limite dans la classe Voiture et tu aurais des classes filles du style Berline, Cabriole, Coupe, avec pour chacune une redéfinition voire une surcharge de cette méthode mais ce n'est en aucun cas une classe.

    Je pense comme wichtounet qu'il s'agit juste d'une liste de méthodes dans ta classe Voiture que tu appelleras en fonction des options que tu auras choisies. Ceci est facilité par le fait que le prix des options ne dépendent pas les unes des autres mais se sont juste des rajouts de prix ou des calculs par rapport au prix de base donc pas de problème

  5. #5
    Membre averti
    Inscrit en
    Mai 2003
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 62
    Par défaut
    Citation Envoyé par sironimo
    Je pense comme wichtounet qu'il s'agit juste d'une liste de méthodes dans ta classe Voiture que tu appeleras en fonction des options que tu auras choisies. Ceci est facilité par le fait que le prix des options ne dépendent pas les unes des autres mais se sont juste des rajouts de prix ou des calculs par rapport au prix de base donc pas de problème
    Oui mais si le client choisi une option, le prix change et doit etre sauve pour le calcul d'une deuxieme option choisie.

  6. #6
    Membre averti
    Inscrit en
    Mai 2003
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 62
    Par défaut
    Voici ma solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    public class Voiture
    {
      //-------------------------------------------------------------------
    
      private String modele;
      private double prix_final;
    
      //-------------------------------------------------------------------
    
      public Voiture(String modele)
      {
        this.modele = modele;
        prix_final = getPrixHT();
      }
    
      //-------------------------------------------------------------------
      
      public String getModele()
      {
        return modele;
      }
      
      //-------------------------------------------------------------------
      
      public double getPrixHT()
      {
        double prixHT;
       
        // le prix est recupere dans une base donnees distante.
        
        return prixHT;
      }
      
      //-------------------------------------------------------------------
      
      public double getPrixFinal()
      {
        return prix_final;
      }
      
      //-------------------------------------------------------------------
      
      public void ajoutBoiteAutomatique()
      {
        prix_final += 500;
      }
      
      //-------------------------------------------------------------------
      
      public void ajoutTraitementAntiCorrosion()
      {
        prix_final += getPrixHT()*8 / 100;
      }
      
      //-------------------------------------------------------------------
      
    }
    Cela nous donne une utilisation extremement simplifiee :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    public class Test
    {
      //-------------------------------------------------------------------
      
      public Test() { }
      
      //-------------------------------------------------------------------
      
      public static void main(String[] args)
      {
        Test test1 = new Test();
        
        Voiture voiture = new Voiture("Toyota");
        
        voiture.ajoutBoiteAutomatique();
        
        voiture.ajoutTraitementAntiCorrosion();
        
        System.out.println("Vous avez achete une " + voiture.getModele() + "\n"
                           + "Son prix initial est de " + voiture.getPrixHT() + "\n"
                           + "Son prix avec option(s) est de " + voiture.getPrixFinal() + "\n");
        
      }
    
      //-------------------------------------------------------------------
    
    }
    Probleme :

    Si le prix dans la base de donnee change apres que l'objet ai ete cree, le prix final ne reflete plus le veritable prix.

  7. #7
    Membre émérite
    Avatar de sironimo
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    669
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Mai 2004
    Messages : 669
    Par défaut
    Bah pourquoi ce prix changerait ?

    Si tu ne fais pas de mise à jour de ton champ prix dans ta base de données, il n'y a aucune raison qu'il change et d'ailleurs, il ne doit pas changer. C'est un prix de base donc fixe. Après, tu vas devoir peut être en définir plusieurs suivant la catégorie de voitures c'est à dire la base de prix d'un 4*4 n'est pas forcément la même que celui d'une familiale, ce genre de nuance. Mais ces prix de base stockés dans la base, ne doivent pas être modifiés en cours d'utilisation.

    Tu peux à la limite faire une petite interface administrateur qui fixe les prix de base suivant les modèles de voiture et ajouter des enregistrements dans ta base de données.

    J'espère ne pas avoir été trop brouillon

  8. #8
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut
    Pour ce genre de cas il y a aussi le pattern du décorateur, dont tu pourras trouver une description ici et . En Java le paquetage java.io est construit sur ce modèle.

    Si tu confirmes que ce modèle peut t'être utile, j'essaierai de te proposer une mise en oeuvre pour toi.

  9. #9
    Membre averti
    Inscrit en
    Mai 2003
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 62
    Par défaut
    Citation Envoyé par gifffftane
    Pour ce genre de cas il y a aussi le pattern du décorateur, dont tu pourras trouver une description ici et . En Java le paquetage java.io est construit sur ce modèle.

    Si tu confirmes que ce modèle peut t'être utile, j'essaierai de te proposer une mise en oeuvre pour toi.
    Oui l'utilisatio de design pattern me sera sans doute tres utile. Aurais-tu une solution a mon probleme ?

    Je vais regarder ce que je peux faire de mon cote.

  10. #10
    Membre averti
    Inscrit en
    Mai 2003
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 62
    Par défaut
    J'aimerais utiliser un pattern du type decorateur (ou strategy ?)

    Voici ma solution mais je n'en suis pas satisfait.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package untitled1;
    
    public class OptionBoiteAutomatique extends Voiture
    {
      private Voiture voiture;
    
      public OptionBoiteAutomatique(Voiture voiture)
      {
        super(voiture.getModele());
        this.voiture = voiture;
      }
    
      public double getPrixHT()
      {
        return voiture.getPrixHT() + 500;
      }
    
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package untitled1;
    
    public class OptionAntiCorrosion extends Voiture
    {
      private Voiture voiture;
    
      public OptionAntiCorrosion(Voiture voiture)
      {
        super(voiture.getModele());
        this.voiture = voiture;
      }
      
      public double getPrixHT()
      {
        return voiture.getPrixHT() + (voiture.getPrixHT()*8)/100;
      }
    
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      public static void main(String[] args)
      {
        Test test1 = new Test();
    
        Voiture voiture = new Voiture("Toyota");
        
        voiture =  new OptionBoiteAutomatique(voiture);
        voiture = new OptionAntiCorrosion(voiture);
    
        System.out.println("Vous avez achete une " + voiture.getModele());
        System.out.println("Son prix est de " + voiture.getPrixHT());
    Une erreur se produit car le prix en ajouter l'opion anticorrosion se fait sur le prix total et non sur le prix de base de la voiture seule.

    Donc en intervertissant les deux options le prix est correct.

    Une idee ? Des remarques ?

  11. #11
    Rédacteur
    Avatar de benwit
    Profil pro
    dev
    Inscrit en
    Septembre 2004
    Messages
    1 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 676
    Par défaut
    J'ai pas tout lu mais face à ton problème d'une voiture avec différentes options, je ferai simplement 2 classes :

    Voiture et Option

    Une voiture ayant une liste d'options : List<Option> options;
    et des méthode addOption(Option option) et removeOption(Option option)

    Option ayant 2 attributs : description et prix

    Pour calculer le prix de la voiture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Voiture voiture = new Voiture();
    voiture.addOption(new Option("boite automatique", 450));
    voiture.addOption(new Option("anticorrosion", 100));
    ...
    ...
    voiture.getPrix();
    ou getPrix() ajoute le prix de base puis parcours la liste des options et ajoute leur prix.

    Je ne sais pas si c'est ce que tu veux, mais c'est flexible car tu peux ajouter les options que tu veux sans avoir à modifier le code. Tu peux même externaliser les options dans un fichier en paramètres.
    En revanche, si tes options sont fixes, tu peut vaire une enum :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    enum Option
    {
         BOITE_AUTO("Boite Auto", 450),
         ANTI_CORROSION("anticorrosion", 100);
    
         Option(String desc, int prix)
         {
            this.desc = desc;
            this.prix   = prix;
         }
    
         String desc;
         int prix;
    }
    et alors :

    voiture.addOption(Option.BOITE_AUTO);
    ...

    Je ne sais pas si cela te convient mais en conception objet, il ne faut pas vouloir caser à tous pris de l'héritage ou des patterns car cela devient alors des anti patterns. Il faut aller au plus simple.

    Je te ferai remarquer que conceptuellement, ton code est complexe car c'est pas évident qu'une Option dérive de Voiture. Une option n'est pas une voiture. Garde l'héritage pour les relations "est un" qui profitent de la redéfinition du code dans les classes filles. Dans les autres cas "est un", préfère les interfaces.

  12. #12
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut
    Je trouve que ce n'est pas mal du tout. Il me semble que tu as compris le pattern (très compliqué, semble-t-il nécessaire de reconnaître) du décorateur.

    Moi j'aurais fait la base sur une classe Option, non sur la classe Voiture : une option n'est tout de même pas une voiture. Mais ton choix peut très bien se justifier pour plein d'autres raisons.

    Concernant ton prix de la bagnole avec les options, il est parfaitement normal que le code fasse la somme de toutes les options... c'est l'avantage du système, justement.

    Pour avoir le prix de la voiture avec seulement anti-corrosion, on fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        Voiture voiture = new Voiture("Toyota");    
        voiture = new OptionAntiCorrosion(voiture); 
        System.out.println("Vous avez achete une " + voiture.getModele());
        System.out.println("Son prix est de " + voiture.getPrixHT());
    Pour avoir le prix avec plein d'autres options :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        Voiture voiture = new Voiture("Toyota");
        
        voiture =  new OptionBoiteAutomatique(voiture);
        voiture = new OptionAntiCorrosion(voiture);
        voiture = new OptionClimatisation(voiture);
        voiture = new OptionGPS(voiture);
    
        System.out.println("Vous avez achete une " + voiture.getModele());
        System.out.println("Son prix est de " + voiture.getPrixHT());
    Pour la bonne forme, précisons qu'un pattern n'est qu'un outil, que l'on peut l'employer ou non, qu'à un problème il existe plein de solutions possibles, et que il est bien évident que celle qu'on a trouvé est la meilleure.


  13. #13
    Rédacteur
    Avatar de benwit
    Profil pro
    dev
    Inscrit en
    Septembre 2004
    Messages
    1 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 676
    Par défaut
    Perso, je ne pense pas que l'utilisation du Pattern Decorateur soit adapté à ton cas. Si on prend un exemple de ce pattern dans la librairie de Swing, c'est ce qui est fait pour les bordures. Dans ce cas, je pense qu'il ce justifie car l'empilement des bordures impact le dessin des bordures suivantes.
    Dans ton cas, il peut se justifier si le prix d'une option dépend du prix d'autres options. Sinon, ça complexifie le modèle pour un apport léger.

    Comme gifffftane, je pense qu'Option aurait été préférable comme classe de base. Ceci dit, et même si je le trouve inapproprié dans ton cas, je pense que tu a compris le pattern et c'est l'essentiel.

  14. #14
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par benwit
    Perso, je ne pense pas que l'utilisation du Pattern Decorateur soit adapté à ton cas.
    +1 ! Je suis tout à fait d'accord sur ce point

    De plus il n'y a aucune notion d'héritage entre une voiture et une option
    • Une voiture n'est pas une option.
    • Une option n'est pas une voiture.


    Par contre on peut dire qu'une voiture comporte possède zéro, un ou plusieurs options...
    c'est de l'agrégation et la solution de benwit me semble la plus adapté !


    Pour preuve prenons deux cas d'utilisation simple :
    • Comment lister toutes les options d'une voiture ?
    • Comment supprimer une option ?

    Ces deux cas sont difficile à mettre en oeuvre si on utilise le pattern décorateur, alors qu'ils sont d'une simplicité évidente avec l'agrégation...


    a++

  15. #15
    Membre averti
    Inscrit en
    Mai 2003
    Messages
    62
    Détails du profil
    Informations forums :
    Inscription : Mai 2003
    Messages : 62
    Par défaut
    Citation Envoyé par adiGuba
    Ces deux cas sont difficile à mettre en oeuvre si on utilise le pattern décorateur, alors qu'ils sont d'une simplicité évidente avec l'agrégation...
    a++
    Qu'est-ce que l'agregation?

    Je vais chercher de mon cote mais aurais tu un example a me proposer?

  16. #16
    Rédacteur
    Avatar de benwit
    Profil pro
    dev
    Inscrit en
    Septembre 2004
    Messages
    1 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 676
    Par défaut
    L'agrégation, c'est ce que j'ai fait dans mon premier message dans la discussion en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public class Voiture
    {
         public void addOption(Option option)
         {
              options.add(option);
         }
    
         public void removeOption(Option option)
         {
              options.remove(option);
         }
    
         public float getPrix()
         {
               float prix = initPrix;
               for(Option option : options)
                   prix += option.prix;
               return prix;
         }
    
         // Une voiture agrège 0, 1 ou n options 
         protected List<Option> options = new ArrayList<Option>();
    
         // Prix de la voiture initiale
         protected float initPrix;
         
    }
    
    public class Option
    {
        public float prix;
        public String description;
    }
    La relation entre la classe Option et la classe Voiture se nomme une agrégation dans ce cas.

  17. #17
    Membre Expert
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Par défaut
    Faites attention que l'aggrégation est encore un pattern est que donc selon certaines théories il risque par hypothèse de compliquer les choses... Au lieu de cela, allez-y directement, faites simple ! Simple ! Qu'est-ce qui nous en empêche ?!

    Cela dit, s'il n'y a que le prix, j'admets que le pattern Simple est le meilleur. (Et l'aggrégation surtout.)

    Cependant, avec le pattern aggrégation, on est mal barré si jamais l'option modifie le comportement ou je ne sais quoi du véhicule. Si par exemple vous devez visualiser l'option gris métallisé, avec bandelettes Formule 1, (ou bandelettes Rallye de Monaco), ou tenir compte de l'option Pneus cloutés pour la tenue de route, cela risque d'être un peu léger avec l'aggrégation...

    Mais enfin, pour Simplifier, j'admets que l'on peut faire plein de choses avec l'aggrégation tout de même.

  18. #18
    Membre émérite Avatar de yann2
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2004
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 897
    Par défaut
    Bonsoir

    Citation Envoyé par gifffftane
    Faites attention que l'aggrégation est encore un pattern est que donc selon certaines théories il risque par hypothèse de compliquer les choses... Au lieu de cela, allez-y directement, faites simple ! Simple ! Qu'est-ce qui nous en empêche ?!

    Cela dit, s'il n'y a que le prix, j'admets que le pattern Simple est le meilleur. (Et l'aggrégation surtout.)

    Cependant, avec le pattern aggrégation, on est mal barré si jamais l'option modifie le comportement ou je ne sais quoi du véhicule. Si par exemple vous devez visualiser l'option gris métallisé, avec bandelettes Formule 1, (ou bandelettes Rallye de Monaco), ou tenir compte de l'option Pneus cloutés pour la tenue de route, cela risque d'être un peu léger avec l'aggrégation...

    Mais enfin, pour Simplifier, j'admets que l'on peut faire plein de choses avec l'aggrégation tout de même.
    Oui, mais dans le problème de départ, une option doit juste nous permettre de recalculer le prix. Toutefois, l'aggrégation seule ne suffit pas.
    En effet, dans son premier post, Xiao-An donne deux exemples d'options :
    - Une ajoute 8% du prix de base.
    - Une ajoute 500 €

    Avec la solution de benwit, nous ne pouvons pas représenter la première option (Ou alors il faudrait recalculer le prix de l'option à chaque changement du prix de base).

    Mais je suis quand même pour la solution la plus simple.
    A savoir :
    Avoir une méthode d'instance dans la classe Option qui calcule le prix de l'option en fonction du prix de base (Et après, il faut prier pour que le client ne complexifie pas le problème).

    Ce qui donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class Voiture {
      public void addOption(Option option)  {
        options.add(option);
      }
      public void removeOption(Option option)  {
        options.remove(option);
      }
      public float getPrix()  {
        float prix = initPrix;
        for(Option option : options) {
           prix += option.calculerPrix(initPrix);
        }
        return prix;
      }
      // Une voiture agrège 0, 1 ou n options
      protected List<Option> options = new ArrayList<Option>();
      // Prix de la voiture initiale
      protected float initPrix;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public abstract class Option {
      private String description;
    
      public abstract float calculerPrix(float prixDeBase);
    
      public String getDescription() {
        return this.description;
      }
    
      public void setDescription(String description) {
        this.description = description
      }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class OptionSimple extends Option {
      private float prix;
    
      public float getPrix() {
        return this.prix;
      }
    
      public void setPrix(float prix) {
        this.prix = prix;
      }
    
      public float calculerPrix(float prixDeBase) {
        return this.prix;
      }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class OptionPourcentage extends Option {
      private float pourcentage;
    
      public float getPourcentage() {
        return this.pourcentage;
      }
    
      public void setPourcentage(float pourcentage) {
        this.pourcentage = pourcentage;
      }
    
      public float calculerPrix(float prixDeBase) {
        return this.pourcentage * 0.01 * prixDeBase;
      }
    }
    Par contre je ne savais pas que l'aggrégation est un Pattern. Je croyais que c'était un concept OO.

    [edit]
    D'ailleurs il est simple de faire en sorte qu'une option puisse modifier le comportement de la voiture. Exemple pour la vitesse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public class Voiture {
      public void addOption(Option option)  {
        options.add(option);
      }
      public void removeOption(Option option)  {
        options.remove(option);
      }
      public float getPrix()  {
        float prix = initPrix;
        for(Option option : options) {
           prix += option.calculerPrix(initPrix);
        }
        return prix;
      }
     
      public float getVitesseMaximale() {
        float vitesse = this.vitesseMax;
        for (Option option : options) {
           if (option instanceof ModificateurVitesse) {
              vitesse = ((ModificateurVitesse) option).calculerBonusVitesse(this.vitesseMax);
           }
        }
        return vitesse;
      }
    
      // Une voiture agrège 0, 1 ou n options
      protected List<Option> options = new ArrayList<Option>();
      // Prix de la voiture initiale
      protected float initPrix;
      // Vitesse maximale
      protected float vitesseMax;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public interface ModificateurVitesse {
      public float calculerBonusVitesse(float vitesseDeBase);
    }
    Ensuite il suffit de créer une classe OptionModifiantLaVitesse, qui hérite de la classe Option et qui implément l'interface ModificateurVitesse.

    En fait le problème majeure est qu'il n'y a aucune interaction entre les options. Pour ce cas, il faudrait quelque chose de plus complexe.
    [/edit]

  19. #19
    Rédacteur
    Avatar de benwit
    Profil pro
    dev
    Inscrit en
    Septembre 2004
    Messages
    1 676
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : dev

    Informations forums :
    Inscription : Septembre 2004
    Messages : 1 676
    Par défaut
    yann2,

    je n'est fait que survolé le problème et je n'ai pas fait attention au cas du %, néanmoins, j'aurai probablement fait comme toi : 2 types d'options.
    (Tu m'as éviter de tout taper )
    au passage, j'aime bien ta proposition d'enrichissement avec l'interface .

    je te rassure, pour moi aussi, l'aggrégation n'est pas un pattern au sens où moi je l'entend. Elle est tellement présente qu'elle est plus pour moi une relation parmi d'autres (aggrégation, composition, association, héritage, implémentation ...)

    j'ai pensé comme toi mais je ne veux pas pinailler car si on traduit "pattern" par "modèle", l'UML qui représente les relations évoquées ci dessus est un langage de modélisation donc je conçois que d'une certaine façon, certains peuvent qualifier les relations (et donc l'agrégation) comme un modèle.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Java] Quel certification choisir ?
    Par amine_en_france dans le forum Certifications
    Réponses: 3
    Dernier message: 26/11/2010, 13h23
  2. web browser en java .. quel composant ?
    Par vdavid1982 dans le forum Composants
    Réponses: 3
    Dernier message: 22/10/2009, 16h08
  3. Réponses: 14
    Dernier message: 19/03/2009, 11h06
  4. [JAVA] Quel EDI JAVA choisir pour Mac OS X ?
    Par didi dans le forum Développement OS X
    Réponses: 18
    Dernier message: 29/09/2007, 22h07
  5. Debutant en Java : Quel EDI choisir ?
    Par raoullandry dans le forum EDI et Outils pour Java
    Réponses: 1
    Dernier message: 22/03/2007, 13h36

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