37 votes

Problème conceptuel de Symfony2: bundles généraux vs spécifiques

J'ai plusieurs questions à propos de mon application Symfony2.

Il aura un frontend et backend, et ils vont utiliser certains codes communs (tels que la date, affichage, paginator, certains modèles souvent utilisés, etc).

Donc, j'ai créé un FrontendBundle et un BackendBundle, chacun contenant par exemple respectifs de mise en page. Première question: est-ce que les bonnes pratiques pour créer des ensembles de frontend et backend, qui sont "général" faisceaux qui ne sera même pas avoir un contrôleur?

Deuxième question: j'ai lu sur un livre de cuisine que je ne devrais pas mettre mes mises en bottes, mais dans app/Resources/views/. J'ai déjà une base.html.brindille de fichier, et je me demande si je devrais mettre ma présentation là aussi, comme un frontend_layout.html.twig fichier?

J'ai créé un bundle nommé RootBundle, qui contiendrait tout ce que mon application doit en frontend ET backend. Est-ce une bonne pratique ou pas? Ou, devrais-je créer un bundle dédié pour chaque fonctionnalités proposées, comme un PaginatorBundle, un DateDisplayerBundle, etc? Il semble bizarre que j'ai un "divers" bundle contenant tout, je ne sais pas où les mettre. Comment faites-vous cela?

80voto

Elnur Abdurrakhimov Points 23540

La nouvelle approche

Après plusieurs mois depuis que j'ai écrit cette réponse, mon approche a changé, je suis donc de les partager avec la communauté. Cette réponse est encore très populaire et peut conduire les nouveaux arrivants à l'approche, je ne pense pas qu'est le meilleur, l'un plus. Alors...

Maintenant je n'ai qu' une application spécifique bundle et j'appelle ça de l' AppBundle. Il y avait plusieurs problèmes avec l'ancienne approche et voici quelques-uns d'entre eux:

  • La création d'un lot de paquets est fastidieux. Vous devez créer une classe bundle et tout un tas de dossiers standard pour chaque nouveau bundle et de l'activer et enregistrer ses routes et ses DI et autres joyeusetés.

  • Inutile hardcore processus de prise de décision. Parfois, vous ne pouvez pas décider de la liasse de quelque chose en particulier appartient, car il est utilisé par plus d'un bundle. Et après vous passez une demi-journée, et enfin faire de votre unité de décision sur l'endroit où le mettre, vous verrez que dans quelques jours ou semaines, vous ne serez pas en mesure de dire immédiatement la liasse de regarder cette chose - parce que la plupart du temps de la décision n'était pas basé sur de la logique pure, et vous aviez à choisir basé sur un tirage au sort ou quel que soit le moyen que vous utilisez pour apporter plus de pouvoirs pour l'aider.

    J'ai suggéré à l'aide de CommonBundle pour les communes de choses dans le passé, mais de faire que vous aurez à faire beaucoup d'inutiles refactorings le déplacement d'une chose et d' CommonBundle basé sur la façon dont beaucoup ou peu de liasses utiliser cette chose plus tard.

  • Application spécifique faisceaux sont interdépendants, de toute façon. Lorsque les gens répondent à l'idée de faisceaux pour la première fois, l'un des principaux de la pensée qui passe par leur esprit est quelque chose comme "Yay!!! Je vais me faire un tas de réutilisables fagots!" Cette idée est excellente et je n'ai rien contre elle; le problème est que d'application spécifiques faisceaux ne sont pas réutilisables de toute façon - là sont interdépendants. Oublier de les réutiliser dans ce cas.

  • Aucune idée de l'endroit où mettre Behat dispose d'étape et de définitions. Ce problème est lié aux précédents: vous devez répéter la même chose sans cervelle motions pour chaque module et ensuite faire hardcore décisions.

    Quand j'ai commencé à écrire Behat fonctionnalités, je n'arrivais pas à décider où mettre beaucoup de fonctionnalités et d'étape définitions parce qu'ils appartenaient à plusieurs paquets à la fois. En les mettant en CommonBundle semblait être encore pire, parce que c'est le dernier bundle je veux le regarder pour ce genre de choses dans. Donc j'ai fini par la création d' FeatureBundle pour que.

La commutation d'un lot unique résolu tous ces problèmes.

J'ai aussi vu des personnes ayant un faisceau, pour ainsi dire, toutes les entités. Je n'aime pas cette approche ni et en fait vous suggérons de garder entités et d'autres non Symfony2 choses spécifiques, de les fagots.

A noter encore que cette nouvelle approche s'applique à application spécifique faisceaux. Officiel de docs et d'autres lieux sont pleins de bons conseils sur la façon de structurer les faisceaux destinés à être partagés avec les autres et réutilisé dans de nombreux projets. J'écris des faisceaux de ce type ainsi. Mais ce que j'ai trouvé après des mois de travail sur les projets Symfony2 est qu'il existe une différence entre les paquets destinés à la réutilisation et à l'app spécifiques - une seule approche ne convient pas à tous.

Et, bien sûr, quand vous voyez quelque chose de réutilisable émergents dans votre application bundle spécifique, il suffit d'extraire, le mettre dans un autre repo et de l'installer en tant que vendeur.

Aussi j'ai trouvé moi-même à l'aide de sous-espaces de noms beaucoup plus activement que d'une façon de partitionner le bundle logiquement - au lieu de créer un tas de fagots, et passer par tous ces troubles.

L'ancienne approche

Il n'existe pas de règles strictes et rapides ou des balles d'argent, mais je vais partager mon approche de faire les choses - peut-être que cela vous donnera une idée ou deux.

Tout d'abord, je n'ai pas de deux qui englobe tout les faisceaux comme FrontendBundle et BackendBundle. Au lieu de cela, mon faisceaux ont à la fois frontend et backend de contrôleurs, de points de vue, etc. Donc, si je bande tout de mon UserBundle , sauf pour les contrôleurs et les vues, sa structure ressemble à ceci:

UserBundle
├── Controller
│   ├── Admin
│   │   └── UserController.php
│   └── UserController.php
├── Resources
│   └── views
│       ├── Admin
│       │   └── User
│       │       ├── add.html.twig
│       │       ├── delete.html.twig
│       │       ├── edit.html.twig
│       │       ├── form.html.twig
│       │       └── index.html.twig
│       └── User
│           ├── edit.html.twig
│           ├── sign-in.html.twig
│           ├── sign-up.html.twig
│           └── view.html.twig
└── UserBundle.php

Deuxièmement, j'ai CommonBundle que j'utilise pour des choses partagée par plusieurs faisceaux:

CommonBundle
├── Resources
│   ├── public
│   │   ├── css
│   │   │   ├── admin.css
│   │   │   ├── common.css
│   │   │   └── public.css
│   │   └── img
│   │       ├── add.png
│   │       ├── delete.png
│   │       ├── edit.png
│   │       ├── error.png
│   │       ├── return.png
│   │       ├── success.png
│   │       └── upload.png
│   └── views
│       ├── Admin
│       │   └── layout.html.twig
│       └── layout.html.twig
└── CommonBundle.php

Mon app/Resources/views/base.html.twig est presque le même comme il est livré avec Symfony Standard de la distribution:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>{{ block('title') | striptags | raw }}</title>
        {% block stylesheets %}{% endblock %}
    </head>
    <body>
        {% block body %}{% endblock %}
        {% block javascripts %}{% endblock %}
    </body>
</html>

Les deux CommonBundle/Resources/views/layout.html et CommonBundle/Resources/views/Admin/layout.html étendre app/Resources/views/base.html.twig. D'autres séries de modèles d'étendre l'une de ces deux dispositions, selon qu'ils sont pour le frontend ou backend. Fondamentalement, ce est ce que je suis en utilisant les Trois niveaux de l'Héritage de l'approche.

Donc, je mettrais votre date d'affichage en CommonBundle. En fonction de sa complexité, il pourrait être juste un modèle, une macro ou une Brindille de l' extension.

La Pagination est un problème commun, donc je vous suggère d'utiliser l'un de l' existant faisceaux au lieu de réinventer la roue, si ils la suite de vos besoins, bien sûr.

Et oui, c'est parfaitement normal d'avoir des paquets sans les contrôleurs ou les points de vue, etc.

4voto

Arms Points 8729

Je suggère la création d'un DateDisplayerBundle et un PaginatorBundle au lieu de mettre leur code dans un cadre plus général de bundle. Il y a quelques raisons à cela:

  • Le rôle de chaque bundle est très clair, et vous savez où votre code.
  • Le partage de morceaux de fonctionnalité (date displayer, paginator) entre les différents projets de est plus simple lorsque vous avez séparé les faisceaux, par rapport à un général bundle que vous, alors peut-être besoin de le tailler.

Il n'y a pas de règle disant que les bottes doivent avoir les contrôleurs. Les faisceaux peuvent avoir n'importe quelle combinaison de la logique d'entreprise, des modèles, des contrôleurs, et de la configuration, mais il n'y a pas de restriction sur ce que vous pouvez stocker dans les.

D'autre part, si votre fonctionnalité n'est pas très complexe, il ne peut pas garantir d'être contenues dans un bundle à tous. Dans ce cas, vous pouvez créer une bibliothèque en /vendor pour elle. Symfony utilise un certain nombre de bibliothèques dans ce mode (voir Monolog et de la Doctrine, par exemple.)

Quant à votre deuxième question, je pense que la raison pour garder mises en app\Resources\views , parce que c'est un moyen pratique pour vous de garder une trace de toutes vos mises en page. Lorsque vous avez un projet qui a de nombreuses offres, vous risquez de perdre la trace de l'endroit où une certaine mise en page est. Mais si vous gardez tout dans un emplacement centralisé, vous saurez toujours exactement où regarder. Comme pour beaucoup de choses dans Symfony2, ce n'est pas une règle qui est gravé dans la pierre. Vous pouvez facilement stocker vos mises en page dans un paquet, mais je ne pense pas que c'est une pratique recommandée.

Comme pour votre question au sujet de votre Racine bundle, je dirais que dans la plupart des cas, vous devriez éviter de shoehorning un tas de différentes fonctions en un seul faisceau. Voir mes points sur la tenue de votre faisceaux spécifiques. Quand j'ai commencé à développer avec Symfony2, j'ai eu quelques difficultés à déterminer ce code devrait aller dans ce bundle. Ce n'est pas la façon dont j'avais l'habitude de penser à la programmation. Mais finalement, vous commencez à voir comment les pièces du puzzle en forme, et qui rend la détermination de la structure de faisceau plus facile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X