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 :

Static, singleton, dependency injector, etc.


Sujet :

Langage PHP

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut Static, singleton, dependency injector, etc.
    Bonjour,

    Depuis ce matin, je regarde comment recoder mon cms (vieux php4 patché pour fonctionner avec php5).

    J'utilise beaucoup de variables globales pour assurer le fonctionnement. J'ai lu beaucoup sur le singleton, et cela ressemble beaucoup à utiliser les variables globales, mais différenment...

    Que pensez-vous de la méthode "dependency injector" ?

    Voici en gros comment fonctionne mon cms:

    Variables globales site, contenant les différents messages bilingues, des configurations diverses, l'url, les langues, etc...

    Classe page, utilisant des objets de classes module passé en parametres. Chaque module sont basés sur des objets de classes action qui gère le tout.

    Chacunes des méthodes de ces objets utilisent la classe site "global $site" pour accéder aux différentes fonctionnalités.

    Devrais-je modifier tout cela pour utiliser un container de dépendance, le passer à la classe page, qui le passera aux objets module, qui le passeront aux objets action?

    De plus, il y a des centaines de fonctions diverses éparpiller un peu partout. Devrais-je les regrouper dans des classes statiques pour créer des bibliothèques?

    Merci,

    Pipo

  2. #2
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    J'utilise beaucoup de variables globales pour assurer le fonctionnement. J'ai lu beaucoup sur le singleton, et cela ressemble beaucoup à utiliser les variables globales, mais différenment...
    C'est pas si différent en réalité, le principe est strictement le même mais en objet. L'énorme défaut du singleton est le couplage qu'il occasionne avec les classes qui l'utilisent. Mais on peut tout de même faire les choses proprement comme avec cette implémentation du pattern.

    Que pensez-vous de la méthode "dependency injector" ?
    L'injection de dépendances solutionne ce problème, il permet de découpler totalement les interface et les rends testables. L'idée est de mettre en place les dépendances au runtime et non de façon statique comme avec le singleton. Voici un exemple d'implementation:
    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
    class IoC {
     
        protected static $_registry = array();
     
        public function register ($name, Closure $fct) {
            static::$_registry[(string)$name] = $fct;
        }
     
        public function resolve ($name) {
            $fct = static::$_registry[(string)$name];
            return inject($fct);
        }
    }
     
    function inject (Closure $fct) {
        $reflect = new ReflectionFunction($fct);
        foreach ($reflect->getParameters() as $parameter) {
            $name = $parameter->name;
            $context[$name] = IoC::resolve($name);
        }
        return !empty($context) ? $reflect->invokeArgs($context) : $reflect->invoke();
    }
     
    IoC::register('a', function ()   { return "a";     });
    IoC::register('b', function ($a) { return "{$a}b"; });
    IoC::register('c', function ($b) { return "{$b}c"; });
     
    inject(function ($a,$b,$c) {
        var_dump($a,$b,$c);
    });

  3. #3
    Nouveau Candidat au Club
    Femme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Merci beaucoup pour ces deux exemples.

    C'est beaucoup plus complexe que je pensais, je vais aller lire plus la dessus et faire quelques tests.

  4. #4
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Ce n'est pas ce qui se fait de plus complexe (attends de tomber sur le pattern Abstract Factory).

    Dans ton cas, je pense que l'injection de dépendances est appropriée: chaque instance doit encapsuler les instances dont elle dépends, par exemple, il serait convenable que tes classes acceptent une instance de Site sur le prototype de leur constructuer afin d'éviter d'avoir recours aux variables globales.

    Mauvais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php
     
    $site = new Site("foobar");
     
    class Layout {
     
      public function build () {
         global $site;
     
         echo "<title>" . $site->title . "</title>";
      }
     
    }
    Bon:

    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
    <?php
     
    class Layout {
     
      protected $_site;
     
      public function __construct (Site $site) {
        $this->_site = $site;
      }
     
      public function build () {
         echo "<title>" . $this->_site->title . "</title>";
      }
     
    }
     
    $site = new Site('foobar');
    $layout = new Layout($site);

  5. #5
    Nouveau Candidat au Club
    Femme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Je croyais qu'un des buts d'utiliser l'injection de dépendance était de pouvoir "briser" les liens entre les différentes classes.

    Dans ton exemple avec le global, on doit clairement utiliser la classe Site, si on veut utiliser la classe Layout.

    Mais dans l'autre exemple aussi, le constructeur s'attend d'avoir un objet Site.

    C'est quelque chose qui m'agace dans la compréhension de ce design pattern. Je comprend parfaitement que c'est plus simple à débugger avec l'injection, on choisit quelle objet Site on désire utiliser, mais en ce qui attrait à l'indépendance des classes, je ne vois pas la différence d'avec les globaux/singleton. Si dans les deux cas, je dois changer quelque chosepar rapport au "title", les deux demandent de modifier la classe Layout.

    Admettons que la classe Layout possède des objets de la classe Module, qui eux possèdent des objets de la classe Action. Si j'ai besoin d'accéder à l'objet $site, dans les Action, je dois les passer en parametre à toutes les classes parentes, même si la classe Module n'en aura pas besoin? N'est-ce pas un peu "overkill" ?

    Merci de ton temps et de tes réponses.

  6. #6
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Si dans les deux cas, je dois changer quelque chosepar rapport au "title", les deux demandent de modifier la classe Layout.
    Pas la classe, l'instance, et pas de la même façon. Il vaut toujours mieux passer une instance en paramètre d'une méthode plutôt que d'avoir recours à global, ceci pour des raisons évidentes de maintenabilité: qu'est ce qu'il se passe si ta variable ne s'appelle plus $site ou si elle n'est plus dans le scope racine ?
    Là où le deuxième exemple utilise une composition en utilisant une interface (qui peut être étendue au passage), donc une relation sémantique claire, le premier utilise une référence dont à priori dans Layout on ne sait rien. Donc dans le premier cas, la dépendance est faite par rapport à l'implem de l'application (ce qui n'est jamais une bonne chose) alors que dans le deuxième, elle est fait par rapport à une autre classe / interface.

    Admettons que la classe Layout possède des objets de la classe Module, qui eux possèdent des objets de la classe Action. Si j'ai besoin d'accéder à l'objet $site, dans les Action, je dois les passer en parametre à toutes les classes parentes, même si la classe Module n'en aura pas besoin? N'est-ce pas un peu "overkill" ?
    Y'a quelque chose qui ne va pas dans ce que tu raconte, j’aimerai bien savoir quel est le lien entre le Layout et les Action parce que ça n'a absolument rien à faire ensemble selon moi.

  7. #7
    Nouveau Candidat au Club
    Femme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2012
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par Benjamin Delespierre Voir le message
    Y'a quelque chose qui ne va pas dans ce que tu raconte, j’aimerai bien savoir quel est le lien entre le Layout et les Action parce que ça n'a absolument rien à faire ensemble selon moi.
    C'était plus à titre d'exemple d'imbrication de 3-4 niveaux et que seulement le dernier niveau nécessite l'accès à la classe. En devant passer une référence à tous les membres, n'est-ce pas trop?

  8. #8
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Si seul un niveau doit avoir accès à une ressource, pourquoi les autres devraient l'encapsuler aussi ?

Discussions similaires

  1. Singleton ou static
    Par yannick1717 dans le forum Général Java
    Réponses: 10
    Dernier message: 29/01/2008, 18h02
  2. GUI, Singleton, fermeture de frame, etc..
    Par Sylver--- dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 14/06/2007, 16h57
  3. methode static Vs singleton
    Par BigNic dans le forum C++
    Réponses: 4
    Dernier message: 22/02/2007, 10h19
  4. [Language][Static vs Singleton] Précisions
    Par vincent63 dans le forum Langage
    Réponses: 6
    Dernier message: 14/11/2005, 17h00
  5. singleton et static
    Par elekis dans le forum C++
    Réponses: 2
    Dernier message: 10/09/2005, 16h11

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