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

Langage Java Discussion :

Choix pour la création de notre propre "Collection"


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    927
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 927
    Par défaut Choix pour la création de notre propre "Collection"
    Salut,

    Pour créer notre propre List on pourrait:
    1. créer une classe qui contiendra une variable List
    2. créer une classe qui dérivera de List ou AbstractList ou ArrayList ... (je ne sais pas quand il est préférable d'utiliser une classe abstraite ou une classe qui implémente déjà une classe non abstraite)

    on pourrait aussi peut être faire cela en (3. ) créant une classe qui implémentera une interface concernant une Collection (je connais pas les noms mais il y a en si je me souviens bien).

    Qu'elles sont les différences entre la première méthode et la deuxième? Et pourquoi pas aussi avec la troisième.
    Conceptuellement, est-ce qu'on ne devrait pas bannir la première méthode? Est-ce que la deuxième méthode devrait se faire en dérivant d'une classe abstraite obligatoirement (AbstractList, AbstractSet) ou ça dépend vraiment du besoin?

    Je me suis posé la question parceque je dois implémenter une liste de type "file d'attente de processus". La liste contiendra des objets caractérisés par des priorités.

    La liste doit implémenter une interface PriorityQ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public interface PriorityQ
    {
    	public static final int LOWEST_PRIO = 0;
    	public boolean put(Object o); 
    	public boolean put(int priority, Object o);
    	public Object get();
    }
    La méthode get doit renvoyer l'objet qui a la priorité la plus élevée. S'il y a plusieurs objets qui ont la même priorité, c'est le premier entré dans la liste que l'on obtiendra.

    J'ai utilisé la 2ème méthode : je fais dérivé ma classe de TreeSet (il faut savoir qu'on doit implémenter cette file de processus à partir de deux Collections différentes et donc je n'ai pas vraiment pensé à quelle Collection conviendrait la mieu, en me disant que ça irait avec n'importe laquelle). Dans ma solution, j'ai aussi utilisé une classe Contenu qui sert à regrouper un objet et sa priorité. Ainsi, quand on utilise la méthode put de l'interface, on stock l'objet et la priorité dans un objet de type Contenu, puis on ajoute cet objet Contenu à ma liste et les méthodes de ma liste s'occuperont de gèrer l'objet Contenu pour que ce soit invisible pour l'utilisateur qui l'utilisera en fonction des méthodes de l'interface.

    Voilà ma liste :
    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    import java.util.AbstractSet;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.Set;
    import java.util.TreeSet;
     
     
    public class FileAPriorité extends TreeSet implements PriorityQ{
     
    	public FileAPriorité (){
    		super();
    	}
     
    	public Object get() {
     
    		Object o = this.first();
    		Contenu c = (Contenu) o;
     
    		this.remove(c);
     
    		return c.getObjet();
     
    	}
     
    	public boolean put(Object o) {
     
    		Contenu c = new Contenu(o, LOWEST_PRIO);
    		this.add(c);
     
     
    		return false;
    	}
     
    	public boolean put(int p, Object o) {
     
    		Contenu c = new Contenu(o, p);
    		this.add(c);
     
    		return false;
    	}
     
     
    	class Contenu implements Comparable{
     
    		private Object objet;
    		private int priorité;
     
    		public Contenu(Object o, int p){
    			objet = o;
    			priorité = p;
    		}
     
    		public Object getObjet(){
    			return this.objet;
    		}
     
    		public int compareTo(Object o) {
    			Contenu c = (Contenu) o;
    			if(this.priorité < c.priorité){
    				return 1;
    			}else if(this.priorité > c.priorité){
    				return -1;
    			}else{
    				return 0;
    			}
    		}
    	}
     
     
     
    }
    Si vous avez des remarques sur ce que j'ai fais, n'hésitez pas, mais j'ai créé le post vraiment pour savoir la différence entre les méthodes citées plus haut. C'est vrai que j'ai pas mal développé mon exercice... comme-ça ce que je ne comprend pas sera peut-être plus compréhensible

    A toute.

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Moi, j'utiliserais une classe comme celle ci :

    java.util.PriorityQueue

    http://java.sun.com/j2se/1.5.0/docs/...rityQueue.html



    Et s'il faut absolument implémenter l'interface souhaitée,

    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
    class FileDePriorite extends PriorityQueue implements PriorityQueue {
      public boolean put (Object o) {
        put(LOWEST_PRIO, o);
      }
     
      public boolean put (int priority, Object o) {
        offer(new PQEntry(priority,o));
      }
     
      public Object get () {
        return poll().value;
      }
     
      private class PQEntry implements Comparable {
        private int priority;
        private Object value;
        PQEntry (int priority, Object value) {
          this.priority=priority;
          this.value = value;
        }
        public int compareTo (Object o) {
          return priority - ((PQEntry)o).priority;
        }
      }
    }

  3. #3
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    927
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 927
    Par défaut
    En effet c'est pas bête
    Ca montre à quel point je suis un étudiant qui s'ai renseigné

    Sinon, j'ai essayé et j'ai du un peu modifier le code

    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
    class FileDePriorite extends PriorityQueue implements PriorityQ {
    	public boolean put (Object o) {  
    		put(LOWEST_PRIO, o); 
    		return true;
    	}   
    	public boolean put (int priority, Object o) {  
    		offer(new PQEntry(priority,o)); 
    		return true;
    		}   
    	public Object get () {  
    		PQEntry e = (PQEntry)this.poll();
    		return e.value; 
    		
    		}   
    	private class PQEntry implements Comparable {  
    		private int priority; 
    		private Object value; 
    		PQEntry (int priority, Object value) {  
    			this.priority=priority; this.value = value; 
    			}  
    		public int compareTo (Object o) {  
    			//return priority - ((PQEntry)o).priority; 
                           // Pour que ça me les renvoie par priorité la plus haute
    			PQEntry c = (PQEntry) o;
    			if(this.priority < c.priority){
    				return 1;
    			}else if(this.priority > c.priority){
    				return -1;
    			}else{
    				return 0;
    			}
    			}  
    		} 
    	}
    Merci pour l'info

    Ca m'amène à penser que ma question est assez vague, imprécise... Je suppose que c'est en fonction des besoins. Mais quand je l'ai posée à mon professeur, il m'a répondu qu'il y avait une très grande différence, que conceptuellement ça changeait tout d'utiliser la méthode 1 ou la 2 (voir premier msg).

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    Oui pour le premier point soulevé, il y a une grosse différence.

    Dans le premier cas, c'est de l'encapsulation (sous réserve de bonne mémoire ) qui permet d'utiliser des objets déjà existants. L'avantage est d'avoir une interface simple qui fait seulement ce qu'on lui demande. L'inconvénient, c'est qu'il n'est pas possible d'utiliser les méthodes utilitaires protected de la classe contenue. Ce système est assez utilisé par le patron de programmation Façade et n'est pas rare dans la programmation orientée objet.

    Dans le second cas, c'est de l'héritage. La plupart du code est déjà écrit et il suffit de redéfinir l'une ou l'autre méthode pour que la classe fasse ce que l'on souhaite. Dans ce cas-ci, en Java, un objet peut rapidement devenir lourd (avec A étend B étend C étend D ... Z) et l'on peut s'y perdre quand on cherche la classe qui implémente réellement la méthode fournie. Mais le gros avantage est la simplicité et la souplesse qu'il permet, utilisé à bon escient. Dans le cadre des List, il est préférable d'étendre AbstractList. Elle définit presque toutes les méthodes par défaut et autorise la réécriture des méthodes les plus critiques (iterator, add, remove, ...) À moins que vous ne préfériez étendre directement ArrayList pour disposer d'une classe toute faite et y ajouter des fonctionnalités que vous considérez manquantes.

  5. #5
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    927
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 927
    Par défaut
    D'accord, merci.

    J'ai encore une petite question : quand j'ai redéfinis la méthode get, j'aurais voulu utiliser la méthode get de la classe d'on on dérive et je me suis rendu compte après plusieurs minutes que ça faisait un appel récursif...

    Dans l'exemple que j'ai posté, j'ai utilisé une autre méthode ("par chance" la classe proposait une autre méthode) parceque je ne vois pas comment faire, à part redéfinir une classe abstraite, genre AbstractList, mais là je me perd vite.

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    1 252
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 252
    Par défaut
    euh... comment c'est possible ?

    La PriorityQueue de java ne définit pas de get() pourtant c'est bien de celle-là qu'on hérite...

    Pour info, si tu veux que la priorité la plus élevée te soit renvoyée, tu peux utiliser mon petit bout de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return priority - ((PQEntry)o).priority;
    et le remplacer par le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return ((PQEntry)o).priority - priority;
    Au lieu de faire un test assez long avec des >, des < et des ==

  7. #7
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    927
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 927
    Par défaut
    Et bien encore merci
    J'ai déjà mis résolu mais en fait... il faut que l'algorithme ne change pas? Ca revient à dire qu'on ne peut faire qu'ajouter des méthodes et que si on redéfinit, ça ne peut apporter que de tout petits changements? Dans mon exemple, j'aurais du utiliser le pattern décorateur?

    Citation Envoyé par dingoth
    euh... comment c'est possible ?

    La PriorityQueue de java ne définit pas de get() pourtant c'est bien de celle-là qu'on hérite...
    En fait je pensais à une autre classe que PriorityQueue, je ne sais plus laquelle c'était mais je sais que la méthode pour récupèrer les éléments de la collection c'était get().

    En fait pour la classe PriorityQueue, j'avais oublié qu'il nous avait interdit de l'utilisé, et on comprend pourquoi... Quoi que la méthode que j'ai utilisé n'était guère plus compliquée que de redéfinir PriorityQueue. Sans utiliser ma classe Contenu ça aurait été un peu plus complexe déjà.

  8. #8
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Par défaut
    Citation Envoyé par goomazio
    Ca m'amène à penser que ma question est assez vague, imprécise... Je suppose que c'est en fonction des besoins. Mais quand je l'ai posée à mon professeur, il m'a répondu qu'il y avait une très grande différence, que conceptuellement ça changeait tout d'utiliser la méthode 1 ou la 2 (voir premier msg).
    Effectivement ca change tout... En conception objet on doit s'efforcer de respecter le PRINCIPE DE SUBSTITUTION DE LISKOV. C'est a dire que si vous faite de l'heritage, votre classe heritée ne doit pas modifier le comportement de la classe mere... Ou en d'autre terme, si un algo utilise la classe mere, vous pouvez substituer la classe mere par la classe heritée, et l'algo continue de fonctionner.

    Donc tant que votre liste "perso" respecte scrupuleusement le contrat de PriorityQueue, vous pouvez etendre PriorityQueue.

    Sinon vous devez utiliser l'encapsulation (ce qui, au passage, s'appelle le pattern decorateur).

    Une regle simple (voir simpliste) consiste a interdire la surcharge de methode. Tant que vous ajoutez des methodes, vous pouvez utiliser l'heritage. Si vous avez besoin de surcharger une methode, retirez l'heritage et utilisez le pattern decorateur... (merci le menu refactor->delegate dans eclipse :-)
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

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

Discussions similaires

  1. Choix d'un script de CMS en PHP pour la création d'un poste de travail
    Par nickoko dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 12/03/2007, 11h01

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