Symfony2概念问题:普通捆绑包与特定捆绑包 [英] Symfony2 conceptual issue: general bundles vs. specific ones

查看:108
本文介绍了Symfony2概念问题:普通捆绑包与特定捆绑包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Symfony最佳做法回答了我的大部分问题.

the Symfony best practices answer most of my questions.

关于我的Symfony2应用,我有几个问题.

I have several questions concerning my Symfony2 app.

它将有一个前端和一个后端,并且它们将使用一些通用代码(例如日期显示器,分页器,一些经常使用的模板等).

It will have a frontend and a backend, and they will use some common code (such as a date displayer, paginator, some templates often used, etc).

因此,我创建了一个FrontendBundle和一个BackendBundle,每一个都包含例如各自的布局.第一个问题:为前端和后端创建捆绑包(这是甚至没有控制器的通用"捆绑包)的优良作法吗?

So, I created one FrontendBundle and one BackendBundle, each containing for example their respective layout. First question: is that good practice to create bundles for frontend and backend, which are "general" bundles which won't even have a controller?

第二个问题:我读过一本食谱,我不应该将布局放在成束的东西中,而应该放在app/Resources/views/目录中.我已经有一个base.html.twig文件了,我想知道是否也应该将布局放在其中,例如frontend_layout.html.twig文件吗?

Second question: I read on a cookbook that I should not put my layouts in bundles, but in the app/Resources/views/ directory. I already have a base.html.twig file in it, and I wonder if I should put my layouts in there too, like a frontend_layout.html.twig file?

我创建了一个名为RootBundle的捆绑包,其中包含我的应用程序在前端和后端所需的所有内容.这是一个好习惯吗?或者我应该为提出的每种功能创建专用的包,例如PaginatorBundle,DateDisplayerBundle等?我有一个杂项"捆绑包,其中包含我不知道放在哪里的所有东西,这听起来很奇怪.你怎么做到的?

I created a bundle named RootBundle, which would contain everything my app needs in frontend AND backend. Is that a good practice or not? Or I should create a dedicated bundle for each functionality proposed, such as a PaginatorBundle, a DateDisplayerBundle, etc? It sounds weird that I have one "miscellaneous" bundle containing everything I don't know where to put. How do you do that?

推荐答案

新方法

自从我写了这个答案几个月后,我的方法发生了变化,因此我要与社区分享.这个答案仍然很受欢迎,并且可以使新来者采用我认为不再是最好的方法.所以...

The new approach

After several months since I wrote this answer, my approach has changed, so I'm sharing it with the community. This answer is still pretty popular and can lead newcomers to the approach I don't think is the best one anymore. So...

现在我只有一个 特定于应用的捆绑包,我称之为AppBundle.旧方法存在一些问题,以下是其中一些:

Now I have only one app specific bundle and I call it AppBundle. There were several problems with the old approach and here are some of them:

  • 创建大量捆绑包很繁琐.您必须为每个新捆绑包创建捆绑包类和一堆标准文件夹,然后激活它并注册其路由和DI等等.

  • Creating a lot of bundles is tedious. You have to create a bundle class and a bunch of standard folders for each new bundle and then activate it and register its routes and DI and whatnot.

不必要的核心决策过程.有时,您无法确定特定事物属于哪个捆绑包,因为某个捆绑包使用了多个捆绑包.在花了半天时间并最终决定将其放置在哪里之后,您会发现在几天或几周内您将无法立即分辨出将哪个东西放在哪个捆绑包中,因为大多数情况下,决策并非基于纯粹的逻辑,因此您不得不基于抛硬币或任何其他手段来做出选择,以借助更大的力量来寻求帮助.

Unnecessary hardcore decision making process. Sometimes you just can't decide which bundle a particular thing belongs to because it's used by more than one bundle. And after you spend a half a day and finally make your hard decision on where to put it, you'll find that in a couple of days or weeks you won't be able to tell right away which bundle to look that thing in — because most of the times the decision wasn't based on pure logic and you had to choose based on a coin toss or whatever means you use to bring higher powers for help.

我过去建议将CommonBundle用于常见内容,但这样做之后,您将不得不进行很多不必要的重构,具体取决于后来有多少捆捆绑使用该东西的事物在CommonBundle之间来回移动. .

I suggested using CommonBundle for common stuff in the past but doing that you'll have to do a lot of unnecessary refactorings moving a thing to and from CommonBundle based on how many or few bundles will use that thing later.

无论如何,特定于应用程序的捆绑软件都是相互依赖的.当人们第一次遇到捆绑软件的想法时,他们脑海中想到的主要思想之一就是是的!我会给我一堆可重复使用的捆绑包!"这个主意很棒,我对此毫不反对.问题在于,特定于应用程序的捆绑包无论如何都不能重复使用,而是相互依赖的.忘记在这种情况下的重用.

App specific bundles are interdependent anyway. When people meet the idea of bundles for the first time, one of the main thought that goes through their minds is something like "Yay! I'll have me a bunch of reusable bundles!" That idea is great and I have nothing against it; the problem is that app specific bundles are not that reusable anyway — there are interdependent. Forget about reuse in this case.

不知道将 Behat 功能和步骤定义放在何处.问题与先前的问题有关:您必须为每个捆绑重复相同的无脑动作,然后做出硬性决定.

No idea where to put Behat features and step definitions. This problem is related to the previous ones: you have to repeat the same brainless motions for each bundle and then make hardcore decisions.

当我开始编写Behat功能时,我无法决定在哪里放置许多功能和步骤定义,因为它们一次属于多个捆绑软件.将它们放入CommonBundle似乎更加糟糕,因为这是我要查找的最后一个包.因此,我最终为此创建了FeatureBundle.

When I started writing Behat features, I just couldn't decide where to put a lot of features and step definitions because they belonged to several bundles at a time. Putting them into CommonBundle seemed to be even worse, because that's the last bundle I would look for that stuff in. So, I ended up creating FeatureBundle for that.

切换到单个捆绑包解决了所有这些问题.

Switching to a single bundle solved all these problems.

我还看到有些人对所有实体都拥有单独的捆绑包.我也不喜欢这种方法,实际上建议将实体和其他非Symfony2特定的内容从捆绑包中排除..

I've also seen some people having a separate bundle for, say, all the entities. I don't like this approach neither and actually suggest keeping entities and other non Symfony2 specific stuff out of the bundles.

再次请注意,这种新方法适用于 app特定的包.官方文档和其他地方对如何构建旨在与他人共享并在多个项目中重复使用的捆绑包提供了很多很好的建议. 我也写了这种类型的包.但是,经过几个月的Symfony2项目研究,我发现用于重用的捆绑包和针对特定应用的捆绑包之间存在差异-一种方法并不适合所有情况.

Note again that this new approach applies to app specific bundles. Official docs and other places are full of great advice on how to structure bundles intended to be shared with others and reused across numerous projects. I write bundles of this type as well. But what I've found out after months of working on Symfony2 projects is that there is a difference between the bundles intended for reuse and the app specific ones — one approach doesn't fit all.

当然,当您看到特定于应用程序的捆绑包中出现了可重用的东西时,只需将其提取出来,放在单独的存储库中并作为供应商进行安装.

And, of course, when you see something reusable emerging in your app specific bundle, just extract it, put it in a separate repo and install as a vendor.

我还发现自己更积极地使用子命名空间作为逻辑上对捆绑软件进行分区的一种方法-而不是为此创建一堆捆绑软件并解决所有这些麻烦.

Also I've found myself using subnamespaces much more actively as a way to partition the bundle logically — instead of creating a bunch of bundles for that and going through all those troubles.

没有硬性规定和快速规则,但我将分享我的处事方法-也许它将为您提供一两次见识.

There are no hard and fast rules or silver bullets, but I'll share my approach of doing things — maybe it will give you an insight or two.

首先,我没有两个包罗万象的包,例如FrontendBundleBackendBundle.相反,我的捆绑包同时包含前端和后端控制器,视图等.因此,如果我从UserBundle中剥离除控制器和视图之外的所有内容,其结构将如下所示:

First of all, I don't have two all-encompassing bundles like FrontendBundle and BackendBundle. Instead, my bundles have both frontend and backend controllers, views, etc. So, if I strip everything from my UserBundle except for controllers and views, its structure would look like this:

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

第二,我有CommonBundle,用于几个捆绑包共享的东西:

Second, I have CommonBundle which I use for stuff shared by several bundles:

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

我的app/Resources/views/base.html.twig几乎与Symfony Standard发行版中的相同:

My app/Resources/views/base.html.twig is almost the same as it comes with Symfony Standard 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>

CommonBundle/Resources/views/layout.htmlCommonBundle/Resources/views/Admin/layout.html都扩展了app/Resources/views/base.html.twig.其他捆绑软件的模板扩展了这两种布局之一,具体取决于它们是用于前端还是后端.基本上,这就是我使用三层继承的方式方法.

Both CommonBundle/Resources/views/layout.html and CommonBundle/Resources/views/Admin/layout.html extend app/Resources/views/base.html.twig. Other bundles' templates extend one of these two layouts, depending on whether they are for frontend or backend. Basically, this is how I'm using the Three-level Inheritance approach.

因此,我将您的日期显示器放入CommonBundle.根据其复杂程度,它可能只是模板,嫩枝

So, I'd put your date displayer into CommonBundle. Depending on its complexity it could be just a template, a macro or a Twig extension.

分页是一个常见问题,所以我建议您使用现有的 而不是重新发明轮子-当然,如果它们适合您的需求.

Pagination is a common problem, so I suggest you to use one of the existing bundles instead of reinventing the wheel — if they suite your needs, of course.

是的,拥有没有控制器或视图等的捆绑包是完全可以的.

And yes, it's perfectly okay to have bundles without controllers or views, etc.

这篇关于Symfony2概念问题:普通捆绑包与特定捆绑包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆