7
votes

Symfony2 mvc: où appartient mon code?

Je demande des éclaircissements sur le fait de mettre le code dans un contrôleur, une entité ou de faire un service.

J'ai des objets "cartectes" et "carte" (où beaucoup de ces derniers sont intégrés dans l'ancien, MongoDB), représentée par des classes / objets PHP normaux. Ceux-ci contiennent des attributs par exemple 'id', 'postal_address'.

J'ai une méthode qui génère un PDF d'une carte. Actuellement, j'ai cela à l'intérieur de l'objet "carte", donc d'un contrôleur que je peux appeler: xxx

qui semble propre et je suppose que je me trompe. < / p>

Si je mets toute la logique du contrôleur qui devient longue et difficile à manier, et je ne suis pas sûr que le contrôleur est l'endroit des méthodes qui agissent sur mes objets. Est-ce ce que sont les services?

Pour résumer et résumer: Si un objet connaît toutes les choses habituelles qu'il pourrait faire "à elle-même" et les avoir à l'intérieur comme des fonctions membres, ou si des méthodes ailleurs sont passées à l'objet agir sur. Si oui, où ces méthodes doivent-elles être conservées?

Je suis à peu près sûr que ce n'est pas un «référentiel» car cela semble aider à récupérer / stocker des entités.

Merci!


0 commentaires

3 Réponses :


7
votes

Réponse courte:

La génération PDF doit être un service, pas une méthode sur un objet.

Réponse plus longue:

En général, et dans Symfony2 surtout, les modèles doivent simplement être utilisés pour stocker des données. Les contrôleurs sont utilisés pour manipuler les relations entre les modèles et les vues sont utilisées pour exprimer les données sous forme humaine ou lisible par ordinateur. Les services sont destinés à des choses qui ne correspondent pas vraiment à l'une des choses ci-dessus qui ne concernent pas l'état de votre application Web.

Un bon exemple est l'envoi d'emails. Les courriels contiennent des données (modèle). Les utilisateurs ont envoyé des emails (contrôleur). Les courriels ont l'air d'une certaine manière (vue). Cependant, l'acte d'envoyer des courriels réellement est indépendant de l'État de l'application Web (tout le service sait qu'il a été invité à envoyer cet e-mail à ces personnes). Ainsi, il est logique qu'il existe un service indépendant qui gère seulement l'envoi d'e-mails.

De même, l'acte de générer des fichiers PDF est indépendant de l'état de l'application Web. Un générateur PDF n'a pas besoin de savoir ce qui se passe dans votre application, il sait simplement qu'il a été invité à faire un PDF.


3 commentaires

Je peux comprendre «envoyer un email» étant un service car c'est un utilitaire. Je veux juste vérifier que ma situation n'est pas différente. Ma méthode de MakePDF () 'n'est pas simplement de faire un PDF (il utilise TCPDF derrière, ce qui ressemble plus à cela), il itre sur des cartes sur un cartonné en faisant chacun un format spécifique de PDF. Donc, c'est étroitement lié à un objet particulier (carte / cartonné) et ne sera jamais jamais donné à celui de travailler avec. Supposons néanmoins le bon endroit pour cela est un service, sans une relation stricte avec l'objet?


Je pense que vous ne pouvez pas dire «en général, et dans Symfony2 surtout, les modèles doivent simplement être utilisés pour stocker des données». En général, les modèles peuvent stocker logique commerciale et des données. Lorsqu'ils stockent uniquement des données, cela s'appelle un modèle anémique et considéré comme anti-motif. Regardez l'entité «rapport». Les exigences disent: "Peut être stocké en tant que fichier". Cela conduit à rapport :: Enregistrer la méthode . Un autre point est que vous devriez découpler THIGNS, et le générateur PDF doit être mis en œuvre en tant que classe séparée (service) et injecté dans votre modèle. PS: makpdf est un mauvais nom.


J'accepte grand chose avec @Meze Commentaire à la non-vote. L'idée de mettre de grandes choses dans le contrôleur est la meilleure façon de dupliquer le code et de la ruine de tester l'efficacité.



7
votes
  • symfony2 n'est pas une structure MVC (comme indiqué par Fabien lui-même) précisément parce qu'elle donne à tous les V (Twig) et C (contrôleurs) mais ne donne pas la partie M. La partie M est "libre" à être construite comme vous le souhaitez.

  • Il y a une confussion majeure, les gens "pensent" que la doctrine est le modèle. Mais ce n'est pas vrai. Ce que nous faisons, c'est deux répertoires dans le paquet, l'un appelé "document" pour les classes doctrine-ODM et une "modèle" où réside la "logique commerciale".

    Personnellement, je vois que $ carte-> makpdf () a du sens ...

    mais $ carte devrait être une "carte de modèle", qui hérite ou a une "carte de données" sous-jacente "qui est la classe de doctrine.

    Vous pouvez jouer avec héritage ou avec des interfaces, avec des créateurs ou tout ce que vous souhaitez relier "Carte de modèle" à "Carte de données", mais la clé est que "la doctrine n'est pas un modèle d'entreprise", il s'agit simplement d'une couche de persistance et votre modèle sont des "classes simples" que vous pouvez construire pour envelopper vos données à l'intérieur et rendre les contrôleurs à consommer le modèle, pas les données.


2 commentaires

C'est de loin l'un des points les plus intéressants que j'ai entendus sur Symfony2 et Doctrine. À propos, comment utilisez-vous un héritage sur des classes de doctrine? La doctrine retourne toujours sa classe d'entité? Si vous avez un peu de temps, vous pouvez regarder Stackoverflow.com/q/15153738


Commenté là-bas. Permettez-moi 24 ou 48 de répondre.



2
votes

Si vous suivrez Solid principes que vous obtiendrez au < Un href = "http://fr.wikipedia.org/wiki/single_responsibilite_principe" rel = "nofollow"> SRP qui indique que votre classe devrait avoir une seule responsabilité.

Je pense qu'il est évident que la génération d'un PDF est quelque chose de différent que de modéliser les données et de mapper votre base de données (votre entité)


0 commentaires