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 :

Comment passer des paramètres lors de sa construction ? [Singleton]


Sujet :

Design Patterns

  1. #1
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut Comment passer des paramètres lors de sa construction ?
    Bonjour,

    Je cherche à créer une classe singleton qui nécessite des paramètres pour sa construction.

    Bien sûr je peux créer une méthode get_instance avec des paramètres et ensuite les transmettre au constructeur, mais une fois le singleton créé ces paramètres deviennent inutiles.

    Je pense simplifier les appels ultérieur à la méthode get_instance avec des valeurs par défaut.

    Le problème c'est que même si l'utilisateur modifie ces paramètres lors d'un second appel, le singleton étant créé, il n'est pas possible de les prendre en compte.

    De ce que j'ai vu, le paramètre d'un singleton est plus utiliser pour modifier le comportement de la méthode get_instance (par exemple pour retourner un élément donné d'une liste).

    Une idée ?

  2. #2
    Membre chevronné
    Avatar de Anthony.Desvernois
    Homme Profil pro
    Ingénieur sécurité & risque
    Inscrit en
    Juin 2007
    Messages
    1 489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur sécurité & risque
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 489
    Points : 2 244
    Points
    2 244
    Par défaut
    Je ne comprends pas trop ce que tu cherches à faire exactement ? Modifier l'instance du singleton selon un/plusieurs paramètres d'appels lors du get_instance ?
    "Voyager, c'est découvrir que tout le monde a tort", Aldous Huxley
    "Less is more" Ludwig Mies Van Der Rohe

    Risk & Security Mgmt

  3. #3
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par Anthony.Desvernois Voir le message
    Je ne comprends pas trop ce que tu cherches à faire exactement ? Modifier l'instance du singleton selon un/plusieurs paramètres d'appels lors du get_instance ?
    Je voulais éviter les aspects technique mais je pense qu'avec un exemple concret ça sera plus simple

    Je créé un widget pour encapsider une fenêtre SDL (bibliothèque pour créer des jeux vidéo). On ne peux créer qu'une fenêtre, donc j'utilise naturellement un singleton.

    Pour créer la fenêtre, il faut préciser sa taille, le nombre de bit par pixel, ... Seulement une fois la fenêtre crée il n'est plus possible de les modifier (ça viens pas de moi, c'est une limitation de la SDL).

    Donc pour un premier appel, il faut utiliser :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    get_instance (680, 480, 32);
    Et ensuite, uniquement :
    C'est plus clair ?

  4. #4
    Membre chevronné
    Avatar de Anthony.Desvernois
    Homme Profil pro
    Ingénieur sécurité & risque
    Inscrit en
    Juin 2007
    Messages
    1 489
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur sécurité & risque
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 489
    Points : 2 244
    Points
    2 244
    Par défaut
    Ok ... Techniquement, je pense que tu pourrais créer des champs qui te permettent de verifier la taille de ton instance, et si les paramètres d'appels sont différents, appeler la méthode de SDL permettant de resizer la fenêtre (si existante) ou alors delete et recrée la fenêtre au bonne dimension. En gros un test quoi
    "Voyager, c'est découvrir que tout le monde a tort", Aldous Huxley
    "Less is more" Ludwig Mies Van Der Rohe

    Risk & Security Mgmt

  5. #5
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par Anthony.Desvernois Voir le message
    appeler la méthode de SDL permettant de resizer la fenêtre (si existante)
    Ah si en fait c'est possible (je chercher pas au bon endroit), je vais donc utiliser une méthode avec des paramètres par défauts et mettre à jour l'affichage en cas de besoin.


  6. #6
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Un truc comme ça, ça suffit pas ?

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    class MaClasse {
      protected MaClasse(Parametre a) {
      }
     
      static private MaClasse instance = null;
      static public getInstance() {
        if(instance==null) throw new IllegalArgumentException("");
        return instance;
      }
      static public getInstance(Parametre a) {
       instance=null;
       instance = new MaClasse(a);
       return getInstance();
      }

    A changer suivant le comportement que tu veux avoir avec getInstance(Parametre)
    Je ne répondrai à aucune question technique en privé

  7. #7
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    Salut,
    Citation Envoyé par millie Voir le message
    Un truc comme ça, ça suffit pas ?

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    :
    :
      static public getInstance(Parametre a) {
       instance=null;
       instance = new MaClasse(a);
       return getInstance();
      }
     
    :
    :
    Oui, mais le hic, c'est que ce n'est plus un singleton là : Si un objet a déjà récupére le getInstance, le fait qu'un autre objet l'appelle va rendre la première réference invalide (null) et retourner une nouvelle, ce qui casse le singleton.

    Sinon, comme la taille de la fenêtre est changeable à souhait, ça n'a plus aucun sens de faire que getInstance prenne des paramètres. Il suffit qu'elle retourne l'unique instance de la fenêtre, qui peut exposer une méthode pour le redimensionnement.

  8. #8
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Bon. On va faire court.
    Tu as besoin d'une variable globale. Tu veux un minimum de sécurité.
    Donc, pas besoin de sortir la construction paresseuse, elle ne te sert strictement à rien [1]. Sans parler des problèmes inhérents à cette construction en environnement multithréadé.

    Donc, un code (C++) qui répond à tes problèmes est le suivant :
    Code c++ : 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
    struct Type : private boost::noncopyable
    {
        /** Accesseur au singleton.
         * @pre ms_instance != 0
         * @throw None
         */
        static Type& instance() { // à découper .h/.cpp évidemment
            assert(ms_instance && "Singleton Type non initialisé!");
            return *ms_instance;
        }
        /** Construction du singleton.
         * @pre ms_instance == 0
         * @post ms_instance != 0
         * @throw TypeException si la globale ne peut être construite
         */
        static void create(paramètres ...) {
            assert(!ms_instance && "Singleton Type déjà initialisé!");
            ms_instance = new Type(paramètres...);
        }
     
        /** Destruction du singleton.
         * @pre ms_instance != 0
         * @post ms_instance == 0
         * @throw None
         */
        void release() {
            assert(ms_instance && "Singleton Type non initialisé!");
            delete ms_instance;
            ms_instance = 0;
        }
     
     
        // + fonctions de l'interface publique de la globale
     
    private:
        Type(paramètres...) { ...}
        ~Type() { ...}
     
        static Type * ms_instance;
    };
     
    // dans un et un seul .cpp uniquement
    Type* Type::ms_instance = 0;
    NB: je l'avais généré automatiquement avec un fichier template (de ma composition) pour vim.

    Edit:
    [1] Car c'est te mentir que de croire qu'elle puisse t'être utile si tu as besoin d'initialiser, de façon précise et non déterminée à la compilation, ton objet.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  9. #9
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Citation Envoyé par djo.mos Voir le message
    Salut,


    Oui, mais le hic, c'est que ce n'est plus un singleton là : Si un objet a déjà récupére le getInstance, le fait qu'un autre objet l'appelle va rendre la première réference invalide (null) et retourner une nouvelle, ce qui casse le singleton.
    C'est pour ça que j'ai dit qu'il fallait éventuellement adapter suivant le besoin que l'on a avec la méthode getInstance(Parametre) qui ne devrait logiquement être appelé qu'une seule fois (sinon, cela n'a pas forcement de sens).
    Je ne répondrai à aucune question technique en privé

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    234
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 234
    Points : 172
    Points
    172
    Par défaut
    Je ne cache pas mon opposition complète au pattern singleton.

    Toutefois en regardant de plus pres le code, le singleton abrite une classe immuable (ce qui parait être un minimum dans l'utilistion de ce pattern), et celle-ci est reinstanciée plusieurs fois au cours de la vie de l'application.

    Je pense tout simplement qu'il ne s'agit pas d'un pattern singleton, et que l'usage de celui-ci n'est vraiment pas approprié (encore moins qu'accoutumée).

    Eventuellement on pourrait passer par un pattern factory si besoin était :
    - une méthode createInstance() qui crée une instance avec des paramètres par défauts ;
    - une méthode createInstance(Parameteres) qui crée une instance avec les paramètres attribuées.

    Le problème de l'unicité de l'instance ne doit pas être gérée au niveau du singleton, mais au niveau de l'objet utilisateur (celui qui apelle un singleton), à travers une simple composition.

    Si l'information doit être connues par plusieurs objets et qu'à priori il n'y a aucun lien entre eux cela signifie qu'il y'a une erreur de conception (il manque par exemple un objet capable de distribuer l'information).

  11. #11
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Points : 545
    Points
    545
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Bon. On va faire court.
    Tu as besoin d'une variable globale. Tu veux un minimum de sécurité.
    Donc, pas besoin de sortir la construction paresseuse, elle ne te sert strictement à rien [1]. Sans parler des problèmes inhérents à cette construction en environnement multithréadé.

    Donc, un code (C++) qui répond à tes problèmes est le suivant :
    Code c++ : 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
    struct Type : private boost::noncopyable
    {
        /** Accesseur au singleton.
         * @pre ms_instance != 0
         * @throw None
         */
        static Type& instance() { // à découper .h/.cpp évidemment
            assert(ms_instance && "Singleton Type non initialisé!");
            return *ms_instance;
        }
        /** Construction du singleton.
         * @pre ms_instance == 0
         * @post ms_instance != 0
         * @throw TypeException si la globale ne peut être construite
         */
        static void create(paramètres ...) {
            assert(!ms_instance && "Singleton Type déjà initialisé!");
            return ms_instance = new Type(paramètres...);
        }
     
        /** Destruction du singleton.
         * @pre ms_instance != 0
         * @post ms_instance == 0
         * @throw None
         */
        void release() {
            assert(ms_instance && "Singleton Type non initialisé!");
            delete ms_instance;
            ms_instance = 0;
        }
     
     
        // + fonctions de l'interface publique de la globale
     
    private:
        Type(paramètres...) { ...}
        ~Type() { ...}
     
        static Type * ms_instance;
    };
     
    // dans un et un seul .cpp uniquement
    Type* Type::ms_instance = 0;
    NB: je l'avais généré automatiquement avec un fichier template (de ma composition) pour vim.

    Edit:
    [1] Car c'est te mentir que de croire qu'elle puisse t'être utile si tu as besoin d'initialiser, de façon précise et non déterminée à la compilation, ton objet.
    La methode create() ne doit - elle pas etre synchonisee en environnement multithreade ?

  12. #12
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    Du tout.
    Comment peut-on créer le singleton, avec paramètres, depuis plusieurs threads à la fois ?
    Je n'y vois ni intérêt ni sens.

    La création a lieu une seule fois avant que les divers threads de l'application ne soient démarrés.

    EDIT: Avec cette forme de singleton, j'écarte la construction paresseuse au profit d'une construction avec paramètres. Ce qui est parfait pour les variables globales métiers que l'on est sensés maitriser, et que l'on désire un minimum blinder (c'est toujours mieux qu'un pointeur global que l'on pourrait oublier de "construire" depuis le main())
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  13. #13
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    Quelque chose d'étonnant dans le code de Luc est le return dans create alors que la signature on a pour valeur de retour void.

    un peu plus long et plus naif (surement pas parfaitement adapté), surtout que j'imagine que tu utilises le langage c++ avec sdl et que le code qui suit est en java..

    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
    public class FenetreSDL 
    {
    	 private FenetreSDL(int pH, int pW, int pB) 
    	  {		
    		 h=pH;
    		 w=pW;
    		 b=pB;
    	  }
    	 
    	  public static FenetreSDL getInstance(int h,int w,int b)
    	   {
    	       if(_instance == null)
    	         return create(h,w,b);
    	       else
    	         return getInstance();
    	   }
    	  
    	   public static FenetreSDL getInstance()
    	   {	      
    	       return _instance;	      	    	  
    	   }
    	   
    	   private static FenetreSDL create(int h,int w, int b)
    	   {
    	      _instance= new FenetreSDL(h,w,b);	       
    	       return _instance;
    	   }
    	   
    	   public static void Terminate()
    	   {
    		  //appel spécifique libération sdl
    	     _instance = null; h=w=b=0;
    	   }
    	   private static FenetreSDL _instance = null;	 
    	   private static int h,w,b;
    }
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

  14. #14
    Membre confirmé

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    162
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 162
    Points : 545
    Points
    545
    Par défaut
    Oui, venant de sa part, je pense que ce ne peut etre qu'une etourderie ...

  15. #15
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    C'est en effet une étourderie. Merci.

    Sinon, le getInstance à paramètres est de trop. Il y a déjà un create() qui est sémantiquement bien plus fort -- mais on retomberait alors sur mon code ^^'
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  16. #16
    Membre Expert

    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Juin 2003
    Messages
    4 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 506
    Points : 5 724
    Points
    5 724
    Par défaut
    oui c'est pour proposer un code différemment de ce qui est déjà proposé que je suis intervenu

    Je me suis plus inspiré de l'utilisation voulue donné comme exemple dans le premier post (le getInstance avec paramètre est déja de trop ^^) et en donnant un nom plus 'sémantique' aussi à la classe.
    " Dis ce que tu veux qui insulte mon honneur car mon silence sera la réponse au mesquin.
    Je ne manque pas de réponse mais : il ne convient pas aux lions de répondre aux chiens ! " [Ash-Shafi'i ]

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

Discussions similaires

  1. Comment passer des paramètres VB6 à Crystal Report
    Par callo dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 12/10/2006, 13h27
  2. [WebForms]Comment passer des paramètres à un UserControl ?
    Par cmoiscrat dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 03/08/2006, 15h03
  3. Réponses: 5
    Dernier message: 31/07/2006, 10h17
  4. Comment passer des paramètre a OpenRecordset
    Par molarisapa dans le forum Access
    Réponses: 2
    Dernier message: 09/03/2006, 17h14
  5. Réponses: 7
    Dernier message: 30/12/2004, 12h01

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