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

Symfony PHP Discussion :

Rôle précis du Controller


Sujet :

Symfony PHP

  1. #1
    Candidat au Club
    Femme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2013
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Novembre 2013
    Messages : 13
    Points : 4
    Points
    4
    Par défaut Rôle précis du Controller
    Salut,

    Je débute avec Symfony et je m'interrogeais quant au rôle exact du controller. Ce que je sais, c'est qu'il contrôle les infos reçues par la vue avant d'interroger le modèle et inversement.
    Ce que je voudrais savoir c'est si je dois écrire toute la partie traitement dans chaque méthode de mon controller ou si ce traitement doit être écrit ailleurs (dans un service peut-être?) et que le controller doit se contenter de l'appeller?

    En bref : où écrire le gros du code? Est-ce normal d'avoir des méthodes de 50 lignes dans un controller?

    Merci à tous,
    Noémie.

  2. #2
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    salutation,

    dans le modèle MVC :
    - le controlleur(C) permet d'effectuer les traitements et les accès aux bases.
    Aucun traitement ne doit être effectué dans la vue, enfin le moins possible.

    si tu as 50 lignes de code dans le controlleur c'est normal si tu ne peux pas faire autrement. comme pour tout programme il faut optimiser son code.


    - les services sont là seulement si tu à besoin d'une fonction à plusieurs endroits, c'est une question de reutisabilité.

  3. #3
    Candidat au Club
    Femme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2013
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Novembre 2013
    Messages : 13
    Points : 4
    Points
    4
    Par défaut
    Salut dukoid,
    Merci de ta réponse, tu me confortes dans mes idées.

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2009
    Messages : 875
    Points : 1 313
    Points
    1 313
    Par défaut
    Personnellement pour un codage plus propre et surtout plus testable, tu peux déléguer le code métier au service. (Pour moi le fait que le contrôleur connaisse l'entity manager est une mauvaise pratique, par exemple).

    Par exemple:
    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
     
    public function createAction(Request $request)
        {
            $entity  = new MyEntity();
            $form = $this->createForm(new MyEntityType(), $entity);
            $form->bind($request);
     
            if ($form->isValid()) {
                //C'est ici qu'on se charge de faire les accès base de données
                $this->get('myentity_service')->createMyEntity($entity);
     
                return $this->redirect($this->generateUrl('some_url'));
            }
     
          /*  [...] */
        }

    Comme ca dans ta classe service qui se fait injecter l'entity manager tu as une méthode createMyEntity($entity) qui est testable facilement, et tu as un service qui regroupe les actions "métiers" de ton application


    Ducoup:
    Ce que je voudrais savoir c'est si je dois écrire toute la partie traitement dans chaque méthode de mon controller ou si ce traitement doit être écrit ailleurs (dans un service peut-être? -> OUI) et que le controller doit se contenter de l'appeller? -> OUI

    En bref : où écrire le gros du code? Est-ce normal d'avoir des méthodes de 50 lignes dans un controller? NON (un contrôleur devrait avoir 30 lignes max et encore ca semble énorme)

  5. #5
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    si le code est utilisé qu'une seule fois je ne vois pas l’intérêt de le mettre dans un service.
    de plus si tu as de nombreuses actions, on ne va pas faire un service pour chaque action.

    un service = une fonction qui peut être utiliser de partout qui du coup peut être facilement testable.

    gotolog, le cas que tu présente est un cas de "reutisabilité" donc parfait pour un service mais n'est pas dans la question d'origine.

  6. #6
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2009
    Messages : 875
    Points : 1 313
    Points
    1 313
    Par défaut
    Je croyais que la question ici était le découpage du controlleur.D'ailleurs je répond exactement à ses questions.

    C'est le même intérêt que de coder la vue à part du controlleur: une séparation des couches et des responsabilités.
    Ca ne veux pas dire un service pour chaque action mais ca se rapproche plus d'un service par controlleur.

    Si après la soumission d'un formulaire de création d'un utilisateur tu dois faire:
    - l'insertion en base de données
    - l'envoi de mail
    - le log d'une interface externe
    - l'envoi de mail au responsable du groupe de l'utilisateur
    J'espère que tu ne fais pas tout ca dans ton contrôleur.

  7. #7
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    l'envois de mail ou le log dont tu parle , vu que se sont des actions "répétitives", des 'fonctions" c'est normal de les mettre sous forme de services.

    la question concerne un code quelconque et volumineux. je n'ai pas lu sauf erreur que c'était une fonctionnalité récurrente.

    donc le fait qu'il soit volumineux n'arrangera rien à ce qu'il se trouve dans un service à moins que tu me donne des arguments techniques dont j'ignore l'existence.

    mais par contre, la solution est d'optimiser le code(ce dont j'ai parlé) et donc de factoriser le code (en service comme tu l'a précisé) si bien sur ce code sera utilisé ultérieurement.

  8. #8
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2009
    Messages : 875
    Points : 1 313
    Points
    1 313
    Par défaut
    J'ai l'impression de lire une approche de découpage procédural...


    Normalement une classe = une responsabilité. En pratique cela peut être lourd, un juste milieu est de limiter au maximum le couplage entre chaque classe.
    Cela ne te choque pas qu'un contrôleur appelle 5 interfaces externe dont il n'est même pas censé connaitre l’existence???

    Par exemple l'exemple ci dessous doit être évité A TOUT PRIX, même si c'est pour du code non volumineux.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    BadAction() {
      $em = $this->get('doctrine')->getManager();
      $em->persist($article)
      $em->flush();
      $this->get('monolog')->info('article créé');
      $this->get('mailer')->send(New Mail('foo@bar.com', 'article '.$article->getName().' créé'));
    }
    Le fait que l'action ci dessous est bonne, ce n'est pas son nombre de ligne, mais la responsabilité de cette action. Elle ne fait qu’être le chef d'orchestre, elle se tamponne l'oreille si la création de l'article se fait en base de données, en session ou en dur dans un fichier. Elle se fou de savoir si on utilise swiftmailer ou une autre librairie. Elle fait son job, simplement.
    D'ailleurs sendArticleCreationMail n'est pas réutilisable, car il envoit que le mail qui correspond à une création d'article.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    GoodAction() {
      $this->get('article_management_service')->create($article); 
      $this->get('mail_service')->sendArticleCreationMail($article);
    }

  9. #9
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    comme solution pour l'optimisation de code c'est bien pensé ce que tu propose mais attention de ne pas se retrouver avec une centaine de service car le remède sera pire que le mal

  10. #10
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    Hello,

    Le contrôleur a pour fonction de récupérer l'objet requête et de renvoyer un objet réponse. Entre les deux il va faire appel à des services pour traiter un formulaire, convertir des données etc.

    Qu'il fasse appel à des services utilisés par d'autres actions ou pas, il est de bon ton de ne pas encombrer le contrôleur avec du traitement métier. Injecter directement lesdits services au contrôleur peut permettre d'avoir une bonne vue d'ensemble du couplage.

    comme solution pour l'optimisation de code c'est bien pensé ce que tu propose mais attention de ne pas se retrouver avec une centaine de service car le remède sera pire que le mal
    Le but n'est pas d'éviter d'avoir une centaine de services dans son projet (en soi ce n'est pas gênant du tout) mais qu'il y ait le moins de dépendance possible. Ca s'applique aussi bien aux contrôleurs qu'au reste d'ailleurs.

    Avec l'exemple de gototog :

    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
    public function createAction(Request $request)
        {
            $entity  = new MyEntity();
            $form = $this->createForm(new MyEntityType(), $entity);
            $form->bind($request);
     
            if ($form->isValid()) {
                //C'est ici qu'on se charge de faire les accès base de données
                $this->get('myentity_service')->createMyEntity($entity);
     
                return $this->redirect($this->generateUrl('some_url'));
            }
     
          /*  [...] */
        }
    personnellement mon action ressemble d'avantage à quelque chose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        /**
         * @Template
         */
        public function createAction()
        {
            if ($this->formHandler->process()->isSuccess()) {
                return $this->redirect($this->generateUrl('some_url'));
            }
     
            return array(
                'form' => $this->formHandler->getFormView()
            );
        }
    Je n'ai pas besoin de plus dans mon contrôleur. Tout est géré par un service formHandler que j'ai injecté au contrôleur. Les actions qui font 50 lignes sont très souvent des erreurs de conception.

    UPDATE : tout ce que vous ne voyez pas (notamment l'objet Request) est passé par injection de dépendance aux différents services utilisés au cours du traitement.

  11. #11
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2009
    Messages : 875
    Points : 1 313
    Points
    1 313
    Par défaut
    J'ai jamais poussé à l'extreme à ce point, mais je me demandais si c'est pas trop galère de mocker la request pour la totalité des tests unitaire?

Discussions similaires

  1. Réponses: 2
    Dernier message: 31/01/2011, 18h47
  2. [JAAS][LDAP] Controle des rôles
    Par Nexussmb dans le forum Sécurité
    Réponses: 0
    Dernier message: 08/09/2008, 11h25
  3. Réponses: 3
    Dernier message: 03/09/2007, 19h02
  4. Réponses: 2
    Dernier message: 12/07/2004, 11h43
  5. Rx Controls Gif animés
    Par toufou dans le forum Composants VCL
    Réponses: 6
    Dernier message: 23/08/2002, 14h09

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