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 PHP Discussion :

Singleton sans constructeur privé


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Avatar de FMaz
    Inscrit en
    Mars 2005
    Messages
    643
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 643
    Par défaut Singleton sans constructeur privé
    Bonjour à tous.

    Alors voilà, actuellement le schéma que j'utilise pour faire un singleton en PHP est celui-ci:

    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
     
    class ConnexionManager
    {
        private static $instance;
        private $arrConn;
     
        private function __construct()
        {
        	$this->arrConn = array();
        }
     
        public static function getInstance() 
        {
            if (empty(self::$instance))
                self::$instance = new ConnexionManager();
     
            return self::$instance;
        }
     
        public function __clone()
        {
            trigger_error('Le clônage n\'est pas autorisé.', E_USER_ERROR);
        }
     
        // ... le reste est tronqué
    }

    Vous allez dire que je suis peut-être exigeant, mais je trouve un peu désagréable de devoir toujours faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $dbMgr = ConnexionManager::getInstance();
    Au lieu de ce qu'on s'attendrait normalement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $dbMgr = new ConnexionManager();

    Alors je me suis demandé s'il était possible de rendre le singleton plus... agréable, et j'en suis venu à penser à ceci:

    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
     
    class ConnexionManager
    {
        private static $instance;
        private $arrConn;
     
        public function __construct() //Constructeur du singleton
        {
            if (!is_object(self::$instance))
            {
                $this->init(func_get_args());
                self::$instance = $this; //L'idée est ici.
            }
            return self::$instance;
        }
     
        public function __clone()
        {
            trigger_error('Le clônage n\'est pas autorisé.', E_USER_ERROR);
        }
     
        private function init($arrParam) //Constructeur de l'objet
        {
             $this->arrConn = array();
        }
        // ... le reste est tronqué
    }


    Cependant, j'ai une sorte de mauvais présentiment, alors je me suis dit que si l'idée était mauvaise, vous aurriez tôt fait de m'indiquer les raisons.


    Alors, vous en pensez quoi ?

  2. #2
    Membre chevronné
    Avatar de FMaz
    Inscrit en
    Mars 2005
    Messages
    643
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 643
    Par défaut
    Je m'auto-répond:

    1.
    Ca ne fonctionnera pas, car $var = new ConnexionManager() ne va pas prendre la valeur retourné par return, mais la valeur de $this.

    2.
    Il est interdit d'assigner une valeur à $this.


  3. #3
    Membre chevronné
    Avatar de FMaz
    Inscrit en
    Mars 2005
    Messages
    643
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 643
    Par défaut
    Par contre, ceci fonctionne:

    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
     
     
    class ConnexionManager
    {
        private static $instance;
        private $arrConn;
     
        public function __construct(&$var) //Constructeur du singleton
        {
            if (!is_object(self::$instance))
            {
                $this->init(func_get_args());
                self::$instance = $this; //L'idée est ici.
            }
            $var = self::$instance;
        }
     
        public function __clone()
        {
            trigger_error('Le clônage n\'est pas autorisé.', E_USER_ERROR);
        }
     
        private function init($arrParam) //Constructeur de l'objet
        {
             $this->arrConn = array();
        }
        // ... le reste est tronqué
    }
    Utilisation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    new ConnexionManager($test1);
    new ConnexionManager($test2);
     
    var_dump($test1 === $test2); //true

    La structure de la classe est certe plus uniforme, mais je ne peux m'empêcher de trouver l'utilisation douteuse.

  4. #4
    Membre Expert Avatar de RunCodePhp
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    2 962
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : Janvier 2010
    Messages : 2 962
    Par défaut
    Salut

    Mais pas seulement pour ça.
    Sauf erreur, le constructeur ne peut pas contenir de return, le constructeur est juste exécuté (théoriquement).

    En tout cas, tu es vraiment exigeant
    Pour ma part, je ne vois rien de désagréable ou dérangeant à faire un Classe::getInstance()

  5. #5
    Membre chevronné
    Avatar de FMaz
    Inscrit en
    Mars 2005
    Messages
    643
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 643
    Par défaut
    En fait, ce qui m'agace, c'est que ce n'est pas transparent. Il faut savoir que l'on a affaire à un singleton pour savoir l'utiliser.

    Je trouve plus "normal" que l'utilisation d'un singleton soit exactement la même que celle d'un objet standard. Le comportement interne ne devrait pas concerner le développeur "externe".

  6. #6
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Citation Envoyé par FMaz Voir le message
    Je trouve plus "normal" que l'utilisation d'un singleton soit exactement la même que celle d'un objet standard. Le comportement interne ne devrait pas concerner le développeur "externe".
    Sauf que ce n'est pas possible. Le but du singleton étant d'avoir une seule et unique instance, tu ne peux logiquement pas passer par un new.

    Il faut savoir que l'on a affaire à un singleton pour savoir l'utiliser.
    Les doc technique sont là pour ça. Avant d'utiliser une class on regarde la doc pour savoir comment elle marche
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juillet 2009
    Messages : 28
    Par défaut
    En noyant le concept de singleton dans une structure fortement objet, on peut arriver à faire comme si ça devenait naturel... je pense à une classe de base, une classe "root" qui implémenterait une méthode "getConnexionManager" et donc héritée par toutes les classes filles ^^

    Après on pourrait peut-être imaginer une classe faite de méthodes abstraites genre "SingletonFactory" et faire des trucs comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $conn = SingletonFactory::getConnexionManager();
    $context = SingletonFactory::getContext();
    Tout dépend du contexte :p
    Après c'est vrai que créer une "SingletonFactory" juste pour récupérer un ConnexionManager... ça fait peu.

    bah... dans ce cas "SingletonUtils" qui englobe des choses spécifiques aux singleton ou "Miscellaneous" qui fait un peu de tout... xD

Discussions similaires

  1. [POO] Singletons et constructeurs
    Par oodini dans le forum C++
    Réponses: 3
    Dernier message: 30/10/2008, 15h28
  2. Classe membre sans constructeur par defaut
    Par TheDrev dans le forum C++
    Réponses: 6
    Dernier message: 28/09/2007, 13h13
  3. Réponses: 14
    Dernier message: 17/11/2006, 20h17
  4. [C#] Une classe sans constructeur, ca existe?
    Par legillou dans le forum Windows Forms
    Réponses: 4
    Dernier message: 03/07/2006, 10h58
  5. [JUnit] [Test][Débutant] Constructeur privé
    Par Shabata dans le forum Tests et Performance
    Réponses: 2
    Dernier message: 12/01/2006, 16h45

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