Injection de dépendances

Aujourd’hui, il est indispensable de passer sur l’injection de dépendances pour des projets durables. L’importance est de faciliter les dépendances entre vos classes.

Définition

Wikipédia est toujours une bonne référence et explique bien ce qu’est l’injection de dépendances fr.wikipedia.org/wiki/Injection_de_dépendances.

Quasiment chaque langage de programmation a son injection de dépendances. Ce n’est pas un outil compliqué car il n’est pas nécessaire d’avoir une librairie pré-compilée pour faire ce travail : vous pouvez le faire directement dans le langage.

Dépendance ?

Votre code a souvent des dépendances vers d’autres classes, c’est bien normal. Cela dépend du langage mais je vais essayer de faire une synthèse.

class Foo {
    public function __construct() {
        $this->bar = new Bar();
    }
}

Vous pouvez voir une dépendance entre la classe Foo et Bar, sans injection. Il y a 2 types d’injections de dépendances pour moi, par le constructeur ou par un appel à une méthode.

class Foo {
    public function __construct(Bar $bar) {
        $this->bar = $bar;
    }
    // ou ..
    public function setBar(Bar $bar) {
        $this->bar = $bar
    }
}

Mais on peut aller encore plus loin car on peut créer une dépendance avec des interfaces, et c’est mieux ! Vous pouvez également le faire via une factory (plus rare) : cela crée plus de dépendances car votre classe sera dépendante de la factory et de ce qu’elle récupère de celle-ci. Dans du langage faiblement typé, vous devrez tester le return de la fonction create ou faire confiance à la classe Factory.

class Foo {
    public function __construct(BarFactory $factory) {
        $this->bar = $factory->create();
    }
    public function setBar(BarInterface $bar) {
        $this->bar = $bar;
    }
}

Injection ?

Les types d’injections de dépendances se complètent. Par exemple on peut faire un constructeur qui demande l’interface d’une factory. Dans le cas de la dépendance, il y a donc 2 façons d’injecter les classes.

En interne, c’est-à-dire directement dans la classe (très lié au premier cas de dépendance).

class Foo {
    public function __construct(BarInterface $bar) {
        $this->bar = $bar;
    }
}
 
$a = new Foo(new Bar());

En externe, ce que je préfère, c’est-à-dire via des fichiers de configuration (XML, YAML, etc.), comme on peut le voir dans Symfony via le service container. Pour information, Symfony est un framework PHP SOA.

Pourquoi autant de moyens pour l’injection de dépendances ?

Attention je n’ai pas dit qu’il y avait strictement que 2 façons d’avoir des dépendances et de les injecter.

En réalité, cela dépend des langages de programmation. Il pourrait y en avoir plus, par exemple via un objet de configuration, via des variables static, public, ou même directement de l’injecteur.
Par contre, on ne fait pas de méthode qui serait le seul point d’entrée aux dépendances (exemple : « injectionDependances(*instances) ») : même s’il y a des cas exceptionnels, cela ne rime à rien ! L’injection de dépendances est un design pattern. De toute façon, la méthode d’injection dépend du besoin métier et de ce que l’on veut obtenir.

Ce qu’il faut retenir, c’est que vous pouvez créer plusieurs objets d’une même classe qui pourront avoir une fonction métier tout à fait différente selon l’injection de dépendances, et ainsi préserver un projet entièrement homogène, configurable et extensible.

L’exemple PHP

PHP a plusieurs projets pour l’injection de dépendances dont 5 qui me viennent à l’esprit :

  • Pimple pimple.sensiolabs.org : simple et efficace qui a pour but d’être petit, rapide et suffisant.
  • Twittee github.com/fabpot/twittee : un injecteur de dépendances de moins de 140 caractères (mon préféré et plus drôle).
  • DependencyInjection github.com/symfony/DependencyInjection : composant Symfony très complet et puissant.
  • DI php-di.org : projet intégré dans Zend (mais non spécifique à celui-ci) qui a pour objectif d’unifier un peu toutes ces librairies. Il ne fait pas parti du FIG (Framework Interop Group).

Pour moi, l’injection de dépendances dans un projet est quelque chose de primordiale d’obligatoire : cela coûte seulement le temps d’écrire les ID de vos classes et évite de faire du Singleton partout dans votre projet (ce qui quelque soit le contexte, n’est pas négligeable).

Pour finir, il existe un tutoriel français pour expliquer, sur le tas, comment faire de l’injection de dépendances dans votre projet :
fr.openclassrooms.com/informatique/cours/introduction-a-l-injection-de-dependances-en-php

 

MongoDB, c’est quoi ? faire du no-sql ou sql ?

MongoDB est une base de données de type No-SQL. Avant d’entrer dans le détail, il serait intéressant de savoir ce que c’est le no-sql.

No-SQL

[fr] http://fr.wikipedia.org/wiki/NoSQL
[en] http://en.wikipedia.org/wiki/NoSQL
[en] http://www.mongodb.com/learn/nosql

Pour faire au plus simple, le No-SQL fait référence aux bases de données qui n’applique pas le modèle classique d’une base de données relationnelle.
Exemple dans MariaDB, les données sont structurées (par table) via un schéma défini. La différence est plus frappante si vous utilisez XtraDB pour ces propriétés ACID. Alors que sur MongoDB, il n’y a pas de schéma est vous sauvegardez des documents par collections.

No-SQL ou SQL ?

Attention je vous préviens dés maintenant, si vous comptez faire un site en NO-SQL vous allez sûrement vous planter, le NO-SQL reste un concept de base de données pour du spécifique. Pour votre projet, imaginez d’abord vos données dans une SGBD relationnelle, il n’y a rien de mieux que la cohérence d’information, ce que vous n’avez pas avec du NO-SQL.

MongoDB

MongoDB est un projet open-source très actif. Ces données sont enregistrées en BSON (du JSON qui permet de gérer plus de types de valeur). Cette SGBD à la chance d’avoir un grand nombre de driver pour des languages comme C, C++, Go, Java, JavaScript, Nodejs, PHP, Python, Ruby, Scala et plus encore.

Vous pouvez très bien utiliser un MongoDB en amont de votre base de données, pour effectuer des traitements rapide sur des éléments précis, faire de la statistique, etc.
MongoDB sera très bien aussi gérer vos sessions utilisateurs, ou faire du cache. Tout ce qui peut être stocké de façon isolé du reste de votre SGBD relationnelle pourrait ce sauvegarder en NO-SQL.

Le SlideShare si-dessous vous illustre mes propos :

http://fr.slideshare.net/FlorentDENIS/mongodb-ekino

Ce qu’il faut savoir

Il faut savoir que MongoDB utilise de la RAM pour les documents les plus demandés, pour des performances optimales il faut avoir autant de RAM que d’espace disque utilisé par MongoDB, voir le working set.
MongoDB allouera de l’espace de stockage à l’avance, au début 64Mo, puis 128Mo, ainsi de suite jusqu’à allouer par paquet de 2Go. Et MongoDB ne supprime pas physiquement ce que vous lui demandé de supprimer, vous devez compacter* votre collection pour supprimer l’inutilisé.
Comme pour un MySQL, MongoDB entretient un journal (vous pouvez squeezer ce journal pour écrire directement sur le disque via des options d’insertion de document). Il est recommandé de placer votre journal sur un autre disque que celui de votre BDD, pour limiter l’I/O.
MongoDB permet de faire du map-reduce sur vos collections, pour effectuer différents traitements ou calcule.
MongoDB tolère la partition* réseau et chaque client voir les mêmes données, ce qui est plutôt agréable. Vous pouvez (voir devez) faire du sharding et de la réplication de données.
MongoDB permet aussi de faire de la géolocalisation sphérique.

[en] http://learnmongo.com/posts/compacting-a-mongodb-collections/
[en] http://www.julianbrowne.com/article/viewer/brewers-cap-theorem
[en] http://blog.nahurst.com/visual-guide-to-nosql-systems
[fr] http://fr.wikipedia.org/wiki/Partition_(base_de_donn%C3%A9es)

Pratiquez

C’est un tour rapide de MongoDB, si vous désirez en s’avoir plus, je ne peux que vous encourager à pratiquer :) J’ai concience de vous avoir envoyez plein d’information d’un seul coup sans explication, mais je préfère montrer la surface et vous pourrez vous faire une idée par vous-même de certain point précis grâce à d’autre articles plus technique sur le web.
Si vous avez des remarques n’hésitez pas.