Ответ 1
Новый подход
Спустя несколько месяцев с тех пор, как я написал этот ответ, мой подход изменился, поэтому я поделился им с сообществом. Этот ответ по-прежнему довольно популярен и может привести новичков к подходу, который я больше не считаю лучшим. Так что...
Теперь у меня есть только один конкретный пакет приложений, и я называю его AppBundle
. Было несколько проблем со старым подходом, и вот некоторые из них:
-
Создание большого количества пакетов является утомительным. Вам нужно создать класс пакетов и набор стандартных папок для каждого нового пакета, а затем активировать его и зарегистрировать его маршруты и DI и многое другое.
-
Ненужный процесс принятия решений по хардкору. Иногда вы просто не можете решить, какой пакет принадлежит определенной вещи, потому что он используется более чем одним пакетом. И после того, как вы потратите пол дня и, наконец, решите свое решение о том, куда его поместить, вы обнаружите, что через пару дней или недель вы не сможете сразу сказать, какой пакет смотреть на эту вещь - потому что в большинстве случаев решение не было основано на чистой логике, и вам приходилось выбирать на основе броска монеты или любого другого средства, которое вы используете, чтобы принести более высокие полномочия для помощи.
Я предложил использовать
CommonBundle
для обычных вещей в прошлом, но при этом вам придется делать много ненужных рефакторингов, перемещая вещи в и изCommonBundle
в зависимости от того, сколько или несколько пакетов будут использовать эту вещь позже. -
Приложения, специфичные для приложения, в любом случае взаимозависимы. Когда люди впервые встречают идею связок, одна из главных мыслей, которая проходит через их умы, - это нечто вроде "Yay! I", У меня есть куча многоразовых пакетов! " Эта идея велика, и я ничего не имею против нее; проблема в том, что приложения, связанные с пакетами, не так много, чтобы повторно использоваться - есть взаимозависимые. Забудьте о повторном использовании в этом случае.
-
Не знаю, куда помещать Behat функции и определения шагов. Эта проблема связана к предыдущим: вы должны повторять одни и те же безмозглые движения для каждого пакета, а затем принимать хардкорные решения.
Когда я начал писать функции Behat, я просто не мог решить, где разместить множество функций и определений шагов, потому что они принадлежали нескольким пакетам за раз. Поставить их в
CommonBundle
, казалось, было еще хуже, потому что в последнем пакете я искал этот материал. Итак, я создал для этогоFeatureBundle
.
Переключение на один пакет решает все эти проблемы.
Я также видел, как некоторые люди имеют отдельный пакет для, скажем, всех сущностей. Мне не нравится этот подход, и на самом деле предлагает сохранить сущности и другие компоненты, отличные от Symfony2, из пакетов.
Заметим еще раз, что этот новый подход применяется к конкретным приложениям. Официальные документы и другие места полны больших советов о том, как структурировать пакеты, предназначенные для совместного использования с другими, и повторно использовать в многочисленных проектах. Я также пишу пакеты этого типа. Но то, что я узнал после нескольких месяцев работы над проектами Symfony2, заключается в том, что существует разница между пакетами, предназначенными для повторного использования, и специфичными для приложения - один подход не подходит всем.
И, конечно, когда вы видите что-то многоразовое, появившееся в вашем конкретном пакете приложений, просто извлеките его, поместите его в отдельное репо и установите в качестве поставщика.
Кроме того, я обнаружил, что более активно использую подносные пространства, чтобы логически разбить пакет, вместо того, чтобы создавать пучки для этого и преодолевать все эти проблемы.
Старый подход
Нет никаких жестких правил или серебряных пуль, но я поделюсь своим подходом делать что-то - может быть, это даст вам понимание или два.
Прежде всего, у меня нет двух всеобъемлющих пакетов, таких как FrontendBundle
и BackendBundle
. Вместо этого у моих пакетов есть интерфейсные и бэкэнд-контроллеры, представления и т.д. Итак, если я отделяю все от моего UserBundle
, за исключением контроллеров и представлений, его структура будет выглядеть так:
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
, который я использую для вещей, разделяемых несколькими пакетами:
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:
<!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.html
и CommonBundle/Resources/views/Admin/layout.html
расширяют app/Resources/views/base.html.twig
. Шаблоны других пакетов расширяют один из этих двух макетов, в зависимости от того, являются ли они интерфейсом или бэкэнд. В основном, это то, как я использую трехуровневый подход наследования.
Итак, я поместил ваш дисплей даты в CommonBundle
. В зависимости от его сложности это может быть просто шаблон, macro или Twig extension.
Разметка является общей проблемой, поэтому я предлагаю вам использовать один из существующий bundles вместо того, чтобы изобретать колесо - если они соответствуют вашим потребностям, конечно.
И да, вполне нормально иметь пакеты без контроллеров или представлений и т.д.