Le Pattern : Singleton

Le pattern Singleton est un design pattern couramment utilisé en programmation orientée objet. Il permet de garantir qu'une seule instance d'une classe est créée dans tout le système, ce qui peut améliorer les performances et simplifier le code. Ce pattern est particulièrement utile pour les objets qui doivent être uniques, tels que les connexions à une base de données ou les objets de configuration.

  • - Probleme

    Le modèle Singleton est un concept très important en programmation orientée objet. Il résout deux problèmes simultanément, mais il est important de noter qu'en faisant cela, il peut violer le Principe de Responsabilité Unique.

    Le premier problème résolu par le modèle Singleton est de garantir qu'une classe n'a qu'une seule instance. Ceci est très utile pour contrôler l'accès à des ressources partagées telles que des bases de données ou des fichiers. Au lieu de créer un nouvel objet chaque fois qu'il est nécessaire d'accéder à cette ressource partagée, le Singleton fournit l'accès à l'unique instance existante. Cela ne peut pas être obtenu avec un constructeur classique car le constructeur doit toujours retourner un nouvel objet.

    Le deuxième problème résolu par le modèle Singleton est de fournir un point d'accès global à cette instance, comme une variable globale, tout en protégeant cette instance contre les écrasements par un autre code. Cela permet d'assurer que tous les utilisateurs de cette instance partagent la même version de l'objet.

    Le modèle Singleton est avantageux car il regroupe le code qui résout le premier problème dans une seule classe. Cela est préférable à disperser le code dans tout le programme, surtout si d'autres parties du code en dépendent. Cependant, le modèle Singleton est si largement utilisé que les gens peuvent qualifier n'importe quoi de singleton même s'il ne résout qu'un des problèmes énumérés. Cela peut entraîner une confusion et des erreurs de conception.

    En somme, le modèle Singleton résout deux problèmes simultanément, mais il est important de considérer son utilisation avec précaution et de s'assurer qu'il est appliqué de manière appropriée pour éviter de violer le Principe de Responsabilité Unique.

  • Toutes les implémentations du Singleton ont ces deux étapes en commun :

    Rendre le constructeur par défaut privé pour empêcher les autres objets d'utiliser l'opérateur "new" avec la classe Singleton.
    Créer une méthode de création statique qui agit comme un constructeur. Cette méthode appelle le constructeur privé pour créer un objet et le sauvegarde dans un champ statique. Tous les appels suivants à cette méthode renvoient l'objet mis en cache.
    Si votre code a accès à la classe Singleton, il peut appeler la méthode statique du Singleton. Ainsi, chaque fois que cette méthode est appelée, le même objet est toujours retourné.

  • Une analogie pour le pattern Singleton est une tour de contrôle de la circulation aérienne à un aéroport. Tout comme un Singleton, il ne peut y avoir qu'une seule tour de contrôle qui gère et dirige le flux de trafic pour tous les avions. Peu importe les contrôleurs aériens de service à un moment donné, la tour de contrôle est un point d'accès unique qui gère le flux de trafic et assure la sécurité de tous les avions. De la même manière, le pattern Singleton garantit qu'il n'y a qu'une seule instance d'une classe qui contrôle l'accès à des ressources partagées ou fournit un point d'accès global.

  • Toutes les implémentations du pattern Singleton partagent deux étapes communes pour garantir qu'une classe possède une seule instance :

    Premièrement, le constructeur par défaut est rendu privé pour empêcher les autres objets d'utiliser l'opérateur new avec la classe Singleton.

    Deuxièmement, une méthode de création statique est créée pour agir comme un constructeur. Cette méthode appelle le constructeur privé pour créer un objet et le sauvegarde dans un champ statique. Tous les appels suivants à cette méthode renvoient l'objet mis en cache.

    En accédant à la classe Singleton, le code peut appeler la méthode statique du Singleton. Chaque fois que cette méthode est appelée, le même objet est toujours renvoyé, garantissant que la classe Singleton ne possède qu'une seule instance.


  • class DatabaseConnection {
    private static $instance = null;
    private $connection;

    private function __construct() {
    $this->connection = mysqli_connect('localhost', 'username', 'password', 'database');
    }

    public static function getInstance() {
    if (self::$instance == null) {
    self::$instance = new DatabaseConnection();
    }
    return self::$instance;
    }

    public function getConnection() {
    return $this->connection;
    }
    }

    $database = DatabaseConnection::getInstance();
    $connection = $database->getConnection();

    Dans cet exemple, la classe DatabaseConnection est un Singleton qui garantit qu'une seule instance de la connexion à la base de données est créée et utilisée dans toute l'application. Voici comment cela fonctionne :

    La variable privée statique $instance contient l'instance Singleton de la classe DatabaseConnection.
    Le constructeur est déclaré comme privé afin qu'il ne puisse pas être accédé depuis l'extérieur de la classe. Cela signifie que la seule façon de créer une instance de la classe est d'utiliser la méthode statique getInstance().
    La méthode getInstance() est déclarée comme publique et statique et est responsable de la création de l'instance Singleton si elle n'existe pas encore. Si elle existe, elle renvoie simplement l'instance existante.
    La méthode getConnection() est une méthode publique qui renvoie l'objet de connexion à la base de données.
    En utilisant un modèle Singleton, nous nous assurons qu'une seule instance de la connexion à la base de données est créée et utilisée dans toute l'application, ce qui peut améliorer les performances et simplifier le code.

    Enfin la classe est instanciée avec la méthode statique DatabaseConnection::getInstance(); et la connexion à la base de donnée récupéré avec la méthode publique $database->getConnection();.