PrestaConcept
Nos réalisations
Nos métiers
  • Découvrez nos métiers
  • Développement web sur mesure

    Nous développons en méthode agile des back sous le framework PHP Symfony, des front en Angular.

  • Maintenance d'applications

    Maintien en condition opérationnelle de votre plateforme Symfony.

  • Expertise Symfony

    Coaching, formation, audit et conseil.

  • Hébergement et Infogérance

    Une expertise de l'hébergement depuis plus de 15 ans et l’infogérance de centaines de machines en production actuellement.

  • Qui sommes nous
  • Découvrez Prestaconcept
  • PrestaConcept

    Notre histoire, nos convictions, notre vision... Découvrez ce qui nous anime !

  • L'équipe

    Plus de 15 ans minimum d'expérience sur Symfony.

  • Nos engagements RSE

    Une société engagée pour un numérique responsable.

  • Nos convictions

    Co-construction, transparence.. Les principes qui guident nos collaborations !

  • Nous rejoindre

    Envie de nous rejoindre ? Consultez nos offres !

  • Blog
    J'ai un projet Nous contacter
    J'ai un projet Nous contacter Menu
    • Accueil
    • Blog
    • Tech
    • Le pattern Chaîne de responsabilité avec Symfony

    Blog

    Le pattern Chaîne de responsabilité avec Symfony

    design pattern php snippet symfony
    Maximilien Delangle
    Maximilien Delangle Développeur Symfony
    Publié le mercredi 20 juillet 2022

    Apprenez à rendre votre code plus léger et maintenable avec le design pattern Chaîne de responsabilité avec Symfony

    Le pattern Chaîne de Responsabilité

    Ce pattern comportemental a pour vocation de créer un ensemble de classes traitant une requête de différentes manières sans avoir conscience de l'objet effectivement responsable du traitement.

    De façon plus concrète l'idée est d'avoir un contrat (classe abstraite ou interface) capable de passer une requête a chacun des objets implémentant ce contrat.

    Voici un schéma décrivant le processus:

    Pattern Chaîne de responsabilité

    En plus de rendre votre application maintenable plus facilement, la structure et le découpage qu'impose ce pattern apporte plus de souplesse et de simplicité à votre code.

    Exemple concret

    Imaginons que votre application doive pouvoir envoyer des notifications à des utilisateurs.

    class MessageService
    {
        public function sendNotification(Message $message): void
        {
            //...
        }
    }
    

    Maintenant on vous demande d'ajouter de nouveaux comportements similaires:

    • Envoyer le message par mail
    • Envoyer le message par sms
    • Envoyer le message vers via une api tierce

    Alors bien évidemment, nous pouvons complexifier notre service afin de le rendre capable d'effectuer toutes ces actions possibles, mais cela risque d'être difficile à maintenir, surtout si d'autres systèmes de communication viennent se greffer petit à petit.
    Et puis n'oublions pas le principe de responsabilité unique qui n'est plus du tout respecté.

    Mise en oeuvre avec Symfony

    Avant de modifier notre service et de créer nos handlers, identifions les avec une interface. Cette interface a pour but d'imposer 2 méthodes:

    • La méthode handle() qui appliquera le code fonctionnel métier correspondant.
    • La méthode getPriority() qui nous permettra d'ordonner nos handlers

    Voici à quoi cela pourrait ressembler.

    namespace App\Notification;
    
    interface MessageSenderInterface 
    {
         public function handle(Message $message): void;
    }
    
    namespace App\Notification;
    
    interface MessageHandlerInterface extends MessagesSenderInterface
    {
         public static function getPriority(): int;
    }
    

    Créer le sender

    Mettons en place le sender, cette classe aura pour métier d'exécuter nos handlers. Il suffit de modifier quelque peu votre service précédemment créé.

    namespace App\Service;
    
    class MessageService implements MessageSenderInterface
    {
        public function __construct(
            /**
             * @var iterable<MessageHandlerInterface>
             */
            private iterable $handlers,
        ) {
        }
        
        public function sendNotification(Message $message): void
        {
            foreach ($this->handlers as $handler) {
                $handler->handle($message);
            }
        }
    }
    

    Créer des handlers

    Ensuite créer quelques handlers.

    namespace App\Notification;
    
    class NotificationHandler implements MessageHandlerInterface
    {
         public function handle(Message $message): void
         {
              //todo envoyer une notification
         }
    
         public static function getPriority(): int
         {
              return 1;
         }
    }
    
    namespace App\Notification;
    
    class SmsNotificationHandler implements MessageHandlerInterface
    {
         public function handle(Message $message): void
         {
              //todo envoyer un SMS
         }
    
         public static function getPriority(): int
         {
              return 2;
         }
    }
    
    namespace App\Notification;
    
    class MailNotificationHandler implements MessageHandlerInterface
    {
         public function handle(Message $message): void
         {
              //todo envoyer un email
         }
    
         public static function getPriority(): int
         {
              return 3;
         }
    }
    

    Utilisation dans un controller

    Nous pouvons maintenant utiliser notre service dans un controller.

    namespace App\Notification;
    
    class FooController
    {
         public function action(MessageSenderInterface $sender): void
         {
              $sender->send($message);
         }
    }
    

    Configurer Symfony

    Nous savons qu'à l'aide de symfony nous pouvons injecter une collection de service. De plus nous pouvons leur donner un ordre de priorité ce qui peut rendre la conception du code plus flexible.

    services:
        _instanceof:
            App\Notification\MessageHandlerInterface:
                tags:
                    - { name: 'notification.handler' }
    
        App\Service\MessageSenderInterface: '@App\Service\MessageService'
        App\Service\MessageService:
            arguments:
                 $handlers: !tagged_iterator { tag: 'notification.handler', default_priority_method: getPriority }
    

    Grâce à cette configuration, notre service recevra une collection d'objets ordonnés via le retour de chaque méthode getPriority().

    Conclusion

    Ce pattern est donc intéressant pour restructurer une classe ayant pour métier de réaliser différentes actions, afin de séparer le code de chaque action en une classe dédiée à chacune d'entre elle.

    Symfony vous aidera à la mise en place de ce pattern. De plus, vous gagnerez en clarté et en légèreté du code, mais aussi en maintenabilité et flexibilité, ce qui permettra une évolution plus rapide.

    Blog

    Pour continuer votre lecture ...

    Tech

    Le pattern Stratégie avec Symfony

    Par Maximilien Delangle 09/02/2023

    C'est un modèle de conception de logiciel qui permet de séparer l'algorithme d'une classe de son exécution. Il est utilisé pour résoudre les problèmes de complexité et de maintenance dans les applications.

    Lire la suite
    Tech

    Le pattern Décorateur avec Symfony

    Par Yann Eugoné 16/03/2022

    Apprenez à découper votre code devenu trop complexe avec le pattern décorateur, en vous aidant de Symfony.

    Lire la suite
    Tech

    Comment désactiver certains listeners lors de certaines commandes

    Par Yann Eugoné 11/01/2022

    Une solution simple et élégante, utilisant l'injection de services tagués, pour vous donner la possibilité de désactiver certains listeners lors de l'exécution de certaines commandes.

    Lire la suite

    Vous avez un projet Laravel ?

    Nous sommes spécialisés en Symfony, et grâce à Web^ID, l’agence sœur du groupe Agile Invest, nous couvrons aussi toute l’expertise Laravel.

    Découvrir Web^ID

    Une question, un projet ?
    Planifiez un échange avec nous !

    Choisissez votre date
    PrestaConcept - Groupe Agile Invest
    5, imp. Morel, 69003 Lyon +33 (0)4 78 54 45 45
    Suivez-nous
    Ecoindex B

    Ce site internet est un site basse consommation. En savoir plus sur l'Ecoindex

    Nos réalisations

  • Logiciel de mise en conformité réglementaire
  • Application de suivi de production des centrales éoliennes
  • Outil d'aide à la décision
  • Portail client
  • Nos métiers

  • Développement sur-mesure
  • Reprise d'application Symfony
  • Expertise Symfony
  • Hébergement & Infogérance
  • Qui sommes-nous

  • PrestaConcept
  • Groupe Agile Invest
  • L'équipe
  • Engagement RSE
  • Blog

  • Tech
  • Méthodologie
  • PrestaConcept
  • RSE
  • © 2025 PrestaConcept
    Mentions légales Politique de confidentialité 🍪
    Retour en haut de page