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

Java Discussion :

[Stratégie] Récupérer une instance existante


Sujet :

Java

  1. #1
    Membre averti
    Inscrit en
    Juillet 2003
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 25
    Par défaut [Stratégie] Récupérer une instance existante
    Bonjour,
    Malgré les quelques mois d'expérience que je commence à avoir, j'ai une question stupide dont je ne trouve pas la réponse.
    Comment récupérer une instance particulière d'une classe?
    En fait j'ai une classe dont le constructeur reçoit des paramêtres et qui au cours de l'exec de mon appli est instanciée à plusieurs reprises.
    J'aimerais en donnant les paramêtres du constructeur récupérer l'instance correspondantes si elle existe (sinon en créer une autre mais là n'est pas le problème).
    Merci de m'aider,
    cm

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 63
    Par défaut
    Une instance est locale au contexte dans lequel elle est invoquée. Quand on sort du bloc de code concernée, ton instance est considérée comme plus référencée, donc supprimable par le garbage collector de java.
    Pour conserver des instances, il faut donc créer un cache d'objets... Donc une autre classe, instanciée une seule fois (singleton) qui garde en permanence une liste d'instances de ta première classe.
    C'est cette factory (ou "home", ou "container", appelle là comme tu veux) que tu appelles ensuite pour créer ou récupérer une instance de ta classe initiale (=> tu n'appelles plus directement le constructeur de ta classe).

  3. #3
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Par défaut
    En fait rien n'est prevu pour ce genre de comportement dans Java..

    Si tu veux faire ce genre de chose il va falloir le gerer toi meme..

    Ce que tu peux faire c'est une factory qui suivant la methode appelee et son nombre de parametres te retourne le singleton equivalent ...

    Bulbo
    [Java] [NetBeans] [CVS]
    La FAQ Java
    Merci de ne pas me poser de questions techniques par MP.

  4. #4
    Membre averti
    Inscrit en
    Juillet 2003
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 25
    Par défaut
    Ma question n'était donc pas si anodine que ça.
    Quelle solution vaut il mieux? Le cache d'objet ou la Factory?
    Auriez vous des liens à ces sujets?
    Merci
    cm

  5. #5
    Membre émérite
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Par défaut
    Tu peux utiliser un dico sous forme de HashMap pour stocker tes instances...

    Et puis si tu ne garde pas de pointeur sur tes instances tu risque de voir le GC passer et supprimer les objets non référenciés (les objets ne sont pas gardés indéfinimment en mémoire, la dé-allocation n'est pas explicite -pas de malloc, free et autre - elle est générée par la JVM)... donc c'est assez aléatoire de retrouver une instance particulière...


  6. #6
    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
    Bonjour,

    tu peux essayer dans ce style là.
    Par contre je n'ai pas eu le temps de tester :
    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
     
    public class Classe {
     
    	private Type attribut1;
    	private Type attribut2;
     
    	private static Vector classes = new Vector();
     
    	private Classe(Type attribut1, Type attribut2) {
    		this.attribut1 = attribut1;
    		this.attribut2 = attribut2;
    	}
     
    	public static Class getInstance(Type attribut1, Type attribut2) {
    		Classe tmp = new Classe(attribut1, attribut2);
    		if (this.classes.contains(tmp)) {
    			// on doit retrouver l'element
    			Enumeration enum = classes.elements();
    			while (enum.hasMoreElements()) {
    				Classe element = (Classe) enum.nextElement();
    				if (element.equals(tmp)) {
    					return element;
    				}
    			}
    		}
    		else {
    			classes.add(tmp);
    			return tmp;
    		}
                                    // si on arrive là, c'est qu'il y à un problème
                                    return null;
    	}
     
    	// ne pas oublier cette méthode 
    	public boolean equals(Objet o1, Object o2) {
    		if (o1 == null || o2 == null) return false;
    		String clsName = "package.Classe";
    		if (o1.getCLass().getName().equals(clsName) && o1.getCLass().getName().equals(clsName)) {
    			return o1.attribut1.equals(o2.attribut1) && o1.attribut1.equals(o2.attribut1);
    		}
    		else return false;
    	}	
     
    }
    Voilà !
    bon courage.

  7. #7
    Membre émérite
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Par défaut
    Ca reviens au même, dans tout les cas tu as une table de hachage sous-jacente...

    Moi j'utiliserai une telle table, dans ce cas tu dois avoir un identificateur UNIQUE pour chaque objet (genre hashCode()).

  8. #8
    Membre averti
    Inscrit en
    Juillet 2003
    Messages
    25
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 25
    Par défaut
    OK merci,
    Je vais voir ce que je peux faire.
    cm

  9. #9
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Par défaut
    Citation Envoyé par thibaut
    Ca reviens au même, dans tout les cas tu as une table de hachage sous-jacente...

    Moi j'utiliserai une telle table, dans ce cas tu dois avoir un identificateur UNIQUE pour chaque objet (genre hashCode()).
    Pas forcement, si tu utilises une factory et que tu veux supporter 3 types de classes differents il te suffit d'avoir trois singletons differents...

    Je ne pense pas qu'il y ai 50 constructeurs differents alors une table de Hash n'est peut etre pas necessaire ..

    Par contre pour avoir une cle unique il suffit d'utiliser la signature du constructeur ... (Constructor.toString())

    Bulbo
    [Java] [NetBeans] [CVS]
    La FAQ Java
    Merci de ne pas me poser de questions techniques par MP.

  10. #10
    Membre émérite
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Par défaut
    Yann c'est ta classe qui s'enregistre elle même...

    Mais tu peux très bien utiliser une factory

    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
    public class Factory {
      private static HashMap _oDico = new HashMap();
     
      ...
      private Object getInstanceDeClasse(Class typeDeClasse) {
        ...
        Object objet = typeDeClasse.newInstance();
        _oDico.put(object.hashCode(), object);
       ...
      }
     
      private Object enregistrer (ObjectEnregistrable objectEnregistrable ) {
        ...
        _oDico.put(objectEnregistrable .hashCode(), objectEnregistrable );
       ...
      }
    }

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 63
    Par défaut
    Dans ton cas, "cache d'objets" et "factory" désignent le meme concept... A savoir une classe qui encapsule toutes les créations d'objets. Dans l'absolu, on peut dire qu'un cache d'objets est une "factory++" (une fabrique qui garde des instances en cache).
    Je ne vais pas te faire ton code, mais grosso modo tu vas avoir :
    - ta Factory : une classe qui implémente de design pattern singleton (= tu ne peux en créer qu'une seule instance) :
    - constructeur par défaut privé
    - un attribut statique "singleton" du type Factory
    - une méthode getFactoryInstance() qui fait le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
       public Factory getFactoryInstance() {
           if (singleton == null) {
               singleton = new Factory();
           }
           return singleton;
       }
    (ah tiens si finalement, je te fais ton code )
    Ca, ça n'a rien à voir avec ton cache d'objets, ca te permet juste de n'avoir qu'une seule instance de Factory (pour n'avoir qu'un seul cache)
    Pour le cache a proprement parler, admettons que la classe dont tu souhaites conserver des instances s'appelle Toto. Il te faut donc dans ta classe factory:
    - un attribut de type ArrayList/Vector/Map/ce que tu veux stockant les différentes instances de Toto (=> c'est ton cache)
    - une méthode getTotoInstance(parametres) qui se chargera, en fonction des paramètres, d'aller chercher l'instance correspondante dans le cache ou de la créer et de l'y ajouter. Ton constructeur de Toto ne sera donc plus appelé que par ta Factory
    Dans les grandes lignes, c'est comme ca que je ferais... Il te reste a voir quelle collection adopter pour stocker tes instances et comment les rechercher efficacement. Ca m'intéressera de voir comment tu fais...

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 63
    Par défaut
    Je me suis fais griller

  13. #13
    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
    J'y suis pour rien moi, je donnais juste un exemple.

    Ca à l'air de marcher ...
    ... et ce n'est pas ridicule.

    C'est exactement le meme prinicpe que les singletons, sauf
    que l'on stock plusieurs instances au lieu d'une (c'est pour cela que ce
    n'est pas un singleton d'ailleurs).

  14. #14
    Membre émérite
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Par défaut
    petite correction pour le multithread, il vaut mieux utiliser le Design Pattern Double Check :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public Factory getFactoryInstance() { 
      if (singleton == null) {
        synchronized ( Factory.class ) {
          if (singleton == null) {
            singleton = new Factory(); 
          }
        }
      } 
      return singleton; 
    }

  15. #15
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 63
    Par défaut
    petite correction pour le multithread, il vaut mieux utiliser le Design Pattern Double Check
    Correction très utile, je ne connaissais pas ce Design Pattern...

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

Discussions similaires

  1. Une erreur 233 de ms sql server
    Par Hokage dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 05/10/2009, 17h40
  2. Erreur 233 sous sql server
    Par brajae85 dans le forum Oracle
    Réponses: 3
    Dernier message: 18/05/2009, 16h12
  3. Réponses: 2
    Dernier message: 05/10/2004, 22h43

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