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

Langage PHP Discussion :

[POO] Modèle MVC, où placer la logique métier


Sujet :

Langage PHP

  1. #1
    Membre confirmé
    Avatar de kalimukti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2011
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Octobre 2011
    Messages : 262
    Points : 451
    Points
    451
    Par défaut [POO] Modèle MVC, où placer la logique métier
    Bonjour,

    Question philosophique: où placer la logique métier dans un modèle MVC (custom ou bien dans des framework comme Code Igniter, Zend...), dans le contrôleur ou le modèle ?

    Si on m'avait posé cette question même il y a un mois, j'aurais sauté sur mon clavier et répondu : "Ben, dans le contrôleur voyons", fier de moi et légitimé par des phrases de tutos telles que :
    "Le contrôleur est le chef d'orchestre de notre application. Il demande au modèle les données, les traite et appelle la vue qui utilisera ces données pour afficher la page.", tirée d'un célèbre MOOC php du web
    Mais
    La partie Modèle d'une architecture MVC encapsule la logique métier (« business logic ») ainsi que l'accès aux données. Il peut s'agir d'un ensemble de fonctions (Modèle procédural) ou de classes (Modèle orienté objet).
    (tuto de développez)
    Moi j'ai toujours pensé que c'est au contrôleur de transformer les données récupérées d'un modèle, de les "digérer" et de les envoyer à la vue/aux vues ensuite...

    Mais en allant du côté des anglo-saxons, on trouve une toute autre approche (celle donnée par ce tuto de développez), qu'on peut lire aussi, par exemple dans cet excellent article:
    résumé par:

    Fat models, skinny controllers!
    Keep as much business logic in the model as possible.
    If you see your controller getting “fat”, consider offloading some of the logic to the relevant model (or else bad things will start happening!).
    Models should not talk to the views directly (and vice versa).
    Related models provide information to the controller via their association (relation).
    It’s quite alright for the views to contain some logic, which deals with the view or presentation.
    dont la traduction de la partie concernant la relation modèle/contrôleur pourrait donner:
    des modèles bien gras, des contrôleurs maigres
    Garder autant de logique métier que possible dans le modèle
    Si vous voyez un contrôleur s'engraisser, réfléchissez à décharger une partie de la logique métier au modèle afférent (ou sinon des problèmes vont commencer à apparaître)
    ....
    J'aimerai connaître votre point de vue / expérience sur le sujet... qu'est-ce qu'il y à gagner à glisser autant de logique métier que possible au modèle plutôt qu'au contrôleur ?
    My daughter, my laptop, my bike and my double-sticks...

  2. #2
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 382
    Points : 10 410
    Points
    10 410
    Par défaut
    Salut,

    En pratique moins tu spécialises le contrôleur général plus il aura la possibilité d'évoluer... On fait souvent différents niveaux de contrôleurs et les plus spécifiques pourront donc se trouver au plus près du modèle.

    Après il y a moult déclinaisons du modèle MVC, donc pas étonnant que tu trouves des informations qui semblent contradictoires et cela dépend aussi du contexte.

  3. #3
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,

    Le contrôleur doit vraiment être perçu comme le chef d'orchestre, c'est à dire qu'il doit savoir à quelle partie du modèle s'adresser pour effectuer une opération particulière, il doit être ensuite capable de disposer pleinement du résultat en provenance du modèle pour finir par savoir quoi en faire. Il peut même bosser un peu si nécessaire en mettant en forme les données pour les passer à d'autres parties du programme.
    Il dirige les opérations sans les faire.

  4. #4
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Le contrôleur n'est pas un chef d'orchestre. C'est un aiguilleur. Un contrôleur reçoit des données entrantes (le plus souvent une requête HTTP), passe cette donnée entrante à un seul objet métier qui s'en occupe, cet objet retourne des données, et le contrôleur renvoie ces données à la vue sous forme de réponse HTTP (éventuellement en les transformant, par exemple en json, xml etc...). Rien de plus, rien de moins. Un contrôleur ne doit pas faire de traitement, ne doit pas utiliser plusieurs objet, rien. C'est un objet "bête", qui se contente juste de recevoir et d'envoyer.

    On a une tendance à confondre Model et la représentation des objets métiers (ce qui explique entre autres pourquoi Doctrine a choisi "entity" et non model). Fat model est une fausse bonne idée si on se tient à la vision MVC traditionnelle du web, où model égale objet ORM: on applique le single responsibility principle aux contrôleurs, mais on transforme les models en God Objects.

    Model représente toute ta partie métier, ton domain layer, qui comprends les entités, les répositories (si tu utilises Data Mapper), plus une infinité d'autres classes et interfaces et fonctions qui font un traitement métier. Fat model ne désigne donc pas une seule classe, mais un domain layer riche. C'est là que tout se passe. La clé, c'est que tu dois organiser ce domain layer pour que chaque responsabilité puisse avoir une porte d'entrée unique que le contrôleur appelle, et qui réalise toutes les opérations qu'on trouvait avant dans le contrôleur.

  5. #5
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Pour faire plus court, si tu vois un "if" (ou un "switch") dans un contrôleur, ce n'est pas bon.

  6. #6
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    @Tsilefy

    Heu... c'est sacrément restrictif comme vision.
    Quand tu sépares les contrôleurs en plusieurs couches tu t'en sors comment ?

    Le contrôleur doit être perçu comme un point d'entrée et sortie de l'application, à ce titre il joue un rôle plus important que celui d'un simple passe-plats.

    Je serai plus proche de la vision de ABCIWEB quand il dit :
    On fait souvent différents niveaux de contrôleurs et les plus spécifiques pourront donc se trouver au plus près du modèle.

  7. #7
    Membre confirmé
    Avatar de kalimukti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Octobre 2011
    Messages
    262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Octobre 2011
    Messages : 262
    Points : 451
    Points
    451
    Par défaut
    Citation Envoyé par Tsilefy Voir le message
    La clé, c'est que tu dois organiser ce domain layer pour que chaque responsabilité puisse avoir une porte d'entrée unique que le contrôleur appelle, et qui réalise toutes les opérations qu'on trouvait avant dans le contrôleur.
    ...
    Pour faire plus court, si tu vois un "if" (ou un "switch") dans un contrôleur, ce n'est pas bon.
    Merci à tous les 3 pour vos réponses... Elles confirment que j'ai bien fait de me/vous poser la question.
    Tsilefy je comprends bien les principes de l'architecture dont tu parles.
    L'idée derrière tout ça est donc d'avoir des contrôleurs évolutifs et maintenables, j'imagine.
    J'ai juste du mal à comprendre qu'est-ce qu'on gagne à confier la logique métier (et donc les if, switch et autres...) aux couches des modèles plutôt qu'à celle des contrôleurs...
    Citation Envoyé par Tsilefy Voir le message
    On a une tendance à confondre Model et la représentation des objets métiers
    Ca veut direque la couche des modèles ne s'occupe pas particulièrement de l'accès aux données, et qu'elle se sert des objets métiers sans nécessairement les définir ?
    Ca me donne l'impression, par rapport à mes habitudes de conception (contrôleur = logique métier + aiguillage // modèle = accès données + objets métiers) qu'il va s'agir pour moi de séparer mes contrôleurs en deux et que la partie logique, je peux la concevoir soit comme une sous-couche des contrôleurs (ce que je comprends de la réponse de ABCIWEB) soit comme une sur-couche de ce que j'ai l'habitude de concevoir comme des modèles... ça vous parle ?
    My daughter, my laptop, my bike and my double-sticks...

  8. #8
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Citation Envoyé par rawsrc Voir le message
    @Tsilefy

    Heu... c'est sacrément restrictif comme vision.
    Quand tu sépares les contrôleurs en plusieurs couches tu t'en sors comment ?

    Le contrôleur doit être perçu comme un point d'entrée et sortie de l'application, à ce titre il joue un rôle plus important que celui d'un simple passe-plats.

    Je serai plus proche de la vision de ABCIWEB quand il dit :
    Je parle en termes de principes, les principes sont toujours restrictifs. Dans la réalité, chacun s'accomode comme il peut.

    Qu'est-ce que tu entends par plusieurs couches? Parce que je suis tenté de te répondre: ton contrôleur fait trop de choses, fais plusieurs contrôleurs.

  9. #9
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    1 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 1 576
    Points : 2 440
    Points
    2 440
    Par défaut
    Citation Envoyé par kalimukti Voir le message
    Tsilefy je comprends bien les principes de l'architecture dont tu parles.
    L'idée derrière tout ça est donc d'avoir des contrôleurs évolutifs et maintenables, j'imagine.
    Oui. Enfin, ça c'est plus la conséquence. L'idée est qu'au fur et à mesure de l'expérience, je découvre de plus en plus qu'il y a un élément fondamental qu'il faut absolument éviter: c'est le couplage. Pour peu que le code soit vivant (un code mort est un code qui ne bouge plus une fois qu'on l'a écrit), qu'on ajoute ou modifie des fonctionnalités, je me rends sérieusement compte des frictions qui existent à chaque fois qu'il y a un couplage (çad une dépendance trop forte) dans le code. Bien évidemment, on apprends tout ça en étudiant la POO, mais dans la pratique c'est encore plus vrai. Et tu réalises que la plupart des principes et des design patterns ont pour but de minimiser (plus ou moins bien) ce couplage.

    D'après le livre du GOF, sur la partie MVC justement:
    Citation Envoyé par Gang Of Four
    Taken at face value, this example reflects a design that decouples views from models. But the design is applicable to a more general problem: decoupling objects so that changes to one can affect any number of others without requiring the changed object to know details of the others.
    Dans le cas qui nous intéresse, en plaçant du code métier dans le contrôleur, tu lies ton application à ce contrôleur. Or, dans la plupart des cas, tu as au moins trois types de "Vues", au sens large:
    - la vue traditionnelle et pubique, un template dans lequel on injecte des données
    - la vue admin, qui utilise parfois les même données que la vue publique, mais avec des données ou des agrégats supplémentaires, ou des fonctionnalités supplémentaires (edition en place, etc...)
    - la vue REST, qui envoie les mêmes données du site à l'application mobile

    Tout ça c'est du très classique, on peut ajouter d'autres vues (ex: une single-page application utilisant un framework javascript), une version mobile si on préfère ça à un design responsive (on ne devrait pas!), etc...

    Dans de telles circonstances, si on fait même un simple traitement dans un contrôleur, on est obligé de le répéter 3 fois (voire 5 fois). Ce serait mieux d'externaliser ce traitement dans une classe que tous les contrôleurs. Ça permet de passer d'un type de controlleur à un autre en envoyant/recevant les mêmes données, en plus, ça permet d'éviter de répéter du code.



    Citation Envoyé par kalimukti Voir le message
    J'ai juste du mal à comprendre qu'est-ce qu'on gagne à confier la logique métier (et donc les if, switch et autres...) aux couches des modèles plutôt qu'à celle des contrôleurs...

    Ca veut direque la couche des modèles ne s'occupe pas particulièrement de l'accès aux données, et qu'elle se sert des objets métiers sans nécessairement les définir ?
    Ca me donne l'impression, par rapport à mes habitudes de conception (contrôleur = logique métier + aiguillage // modèle = accès données + objets métiers) qu'il va s'agir pour moi de séparer mes contrôleurs en deux et que la partie logique, je peux la concevoir soit comme une sous-couche des contrôleurs (ce que je comprends de la réponse de ABCIWEB) soit comme une sur-couche de ce que j'ai l'habitude de concevoir comme des modèles... ça vous parle ?
    La couche modèle s'occupe de l'accès aux données, mais pas seulement. Il représente l'état de l'application, et modifie donc cet état en fonction des demandes en réalisant des opérations métiers.

    Dans tous les points de vue, le mien comme celui d'ABCIWEB et Sabotage, la logique métier doit sortir du contrôleur. Si l'on sort du cadre strict du MVC (et l'on devrait, MVC n'est pas un modèle parfait), ce que tu appelles logique métier (encore faut-il que tu le définisses) est réalisé par exemple par le Pattern command et les command bus, qui permet une composition de traitements successifs sans alourdir le contrôleur et sans alourdir les modèles (au sens entity). Dans ce cas, la méthode du contrôleur contient effectivement une seule ligne effective (si on ne compte pas les try/catch)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public function testController(Request $request)
    {
        //$testCommand est injecté quelque part dans le contrôleur.
        try {
           $this->testCommand->execute($request);
        }
       //suit une suite de catch
    }
    On va ainsi vraiment au bout de cette logique, et c'est assez extrême, mais l'avantage c'est qu'on peut utiliser la commande et le command bus n'importe où dans l'application, pas seulement dans un contrôleur. La commande encapsule à la fois des données, un état et une action, alors que traditionnellement un objet encapsule juste des données et un état. Pouvoir encapsuler et réutiliser cette action n'importe où apporte beaucoup d'avantages.

    Après c'est l'extrême du raisonnement. Il faut juste savoir que ça se fait, mais tu n'es pas obligé de l'appliquer.

  10. #10
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

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

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 382
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par kalimukti Voir le message
    ... la partie logique, je peux la concevoir soit comme une sous-couche des contrôleurs (ce que je comprends de la réponse de ABCIWEB) soit comme une sur-couche de ce que j'ai l'habitude de concevoir comme des modèles... ça vous parle ?
    Oui c'est une possibilité. Tu peux avoir un contrôleur général qui fait appel à des contrôleurs secondaires etc. qui eux seront spécifiques à une tâche définie. Ainsi si tu as besoin de faire du couplage et donc de créer des dépendances - parce que cela peut être très long et pas forcément rentable de les éviter - tu pourras le faire au "plus bas niveau possible" et un changement à ce niveau n'impactera pas le niveau supérieur. A défaut de pouvoir éviter toutes les dépendances on les repousse vers le bas de la pyramide, là où elles sont le moins gênantes.

Discussions similaires

  1. ASP.Net MVC rend-il la logique métier portable?
    Par Immobilis dans le forum ASP.NET MVC
    Réponses: 10
    Dernier message: 09/09/2011, 08h54
  2. [POO] Modèle MVC et appel de controller
    Par sourivore dans le forum MVC
    Réponses: 9
    Dernier message: 13/09/2009, 03h16
  3. Où placer la logique métier ?
    Par oranocha dans le forum Zend_Db
    Réponses: 3
    Dernier message: 29/07/2009, 19h46
  4. Réponses: 4
    Dernier message: 08/10/2008, 13h07
  5. Architecture J2EE et modèle MVC
    Par alexd dans le forum Développement Web en Java
    Réponses: 4
    Dernier message: 23/02/2005, 15h59

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