Digital solutions
Design Patterns avec Laravel

Registry Pattern

  • Type : Structurel
  • Difficulté : 4/10
  • Définition succincte : Le Registry Pattern est un design pattern structurel qui permet de centraliser l'accès global à des objets ou services partagés à travers l'application. Le registre agit comme un conteneur global dans lequel les objets peuvent être ajoutés, récupérés, et supprimés. Cela permet d'éviter la création d'instances multiples de services ou d'objets souvent utilisés, en centralisant leur accès à un seul endroit.

Objectif du Registry Pattern

L'objectif principal du Registry Pattern est de fournir un point d'accès global à des objets partagés à travers l'application, tout en évitant de devoir les instancier à plusieurs endroits. Il permet également de réduire le couplage en centralisant la gestion des objets et services.

Structure du Registry Pattern

  • Registry : La classe qui stocke et gère les objets et services.
  • Client : Le code ou les classes qui accèdent aux objets ou services à partir du registre.

Implémentation avec Laravel

Imaginons une application Laravel où plusieurs services, comme un service de notification, un service d'envoi d'emails, et un service de paiement, doivent être accessibles à plusieurs endroits dans l'application. Le Registry Pattern permet de centraliser l'accès à ces services via un registre global.

a) Créer la classe Registry

Voici un exemple simple d'un registre qui permet d'ajouter, récupérer et supprimer des objets.

// app/Patterns/Registry.php

namespace App\Patterns;

class Registry
{
    private static array $services = [];

    // Ajouter un service dans le registre
    public static function set(string $key, $service): void
    {
        self::$services[$key] = $service;
    }

    // Récupérer un service depuis le registre
    public static function get(string $key)
    {
        if (!isset(self::$services[$key])) {
            throw new \InvalidArgumentException("No service found for key {$key}");
        }
        return self::$services[$key];
    }

    // Supprimer un service du registre
    public static function remove(string $key): void
    {
        unset(self::$services[$key]);
    }
}

b) Enregistrer des services dans le registre

Supposons que nous ayons plusieurs services, tels que EmailService, PaymentService, et NotificationService, que nous voulons centraliser dans le registre.

Exemple de services
// app/Services/EmailService.php

namespace App\Services;

class EmailService
{
    public function sendEmail($to, $subject, $message)
    {
        // Logique d'envoi d'email
        return "Email sent to {$to} with subject: {$subject}";
    }
}
// app/Services/PaymentService.php

namespace App\Services;

class PaymentService
{
    public function processPayment($amount)
    {
        // Logique de traitement de paiement
        return "Processed payment of \${$amount}";
    }
}
// app/Services/NotificationService.php

namespace App\Services;

class NotificationService
{
    public function sendNotification($user, $message)
    {
        // Logique d'envoi de notification
        return "Notification sent to {$user} with message: {$message}";
    }
}

c) Utilisation du Registry Pattern dans une commande CLI

Nous allons maintenant créer une commande CLI pour tester l'enregistrement et l'utilisation des services via le Registry Pattern.

1. Commande TestRegistry

Cette commande enregistre les services dans le registre et les utilise pour exécuter des tâches comme l'envoi d'emails, le traitement de paiements, et l'envoi de notifications.

// app/Console/Commands/TestRegistry.php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\Patterns\Registry;
use App\Services\EmailService;
use App\Services\PaymentService;
use App\Services\NotificationService;

class TestRegistry extends Command
{
    protected $signature = 'registry:test';
    protected $description = 'Test the Registry Pattern by registering and using services';

    public function handle()
    {
        // Enregistrer les services dans le registre
        Registry::set('email', new EmailService());
        Registry::set('payment', new PaymentService());
        Registry::set('notification', new NotificationService());

        // Utiliser le service email
        $emailService = Registry::get('email');
        $this->info($emailService->sendEmail('test@example.com', 'Hello', 'This is a test email.'));

        // Utiliser le service de paiement
        $paymentService = Registry::get('payment');
        $this->info($paymentService->processPayment(100));

        // Utiliser le service de notification
        $notificationService = Registry::get('notification');
        $this->info($notificationService->sendNotification('John Doe', 'You have a new message.'));

        // Supprimer un service du registre
        Registry::remove('email');
    }
}

d) Exécution de la commande

Tu peux maintenant exécuter la commande pour voir comment les services sont enregistrés, récupérés, et utilisés via le registre :

php artisan registry:test

Résultat attendu :

Email sent to test@example.com with subject: Hello
Processed payment of $100
Notification sent to John Doe with message: You have a new message.

Avantages du Registry Pattern

  1. Point d'accès global : Le Registry Pattern fournit un point d'accès centralisé pour les services partagés à travers l'application, ce qui évite de devoir les instancier à plusieurs endroits.
  2. Simplification du code client : Les services sont stockés et accessibles facilement, ce qui simplifie leur gestion dans le code client.
  3. Réduction des dépendances : En centralisant les services dans un registre global, tu réduis les dépendances directes dans les parties clientes du code.

Inconvénients du Registry Pattern

  1. Problème de globalité : Comme le registre centralise les objets au niveau global, cela peut introduire des dépendances globales qui vont à l'encontre des bonnes pratiques de conception comme l'injection de dépendances.
  2. Difficulté de testabilité : Le registre global peut rendre les tests unitaires plus difficiles à isoler, car il nécessite de manipuler les objets dans un espace global.
  3. Couplage fort : Le code client peut devenir fortement couplé au registre, ce qui peut rendre l'évolution du système plus complexe.

Conclusion

Le Registry Pattern est un moyen efficace de centraliser l'accès à des services partagés dans une application Laravel. Il fournit un point d'accès global aux services, ce qui simplifie leur gestion et évite leur duplication. Cependant, il introduit des dépendances globales qui peuvent compliquer les tests unitaires et l'évolution du système. Dans certains contextes, ce pattern peut être avantageux, mais il faut l'utiliser avec prudence pour éviter de créer un couplage trop fort et des dépendances globales non nécessaires.