Symfony2 problem koncepcyjny: Pakiety Ogólne a Pakiety szczegółowe

Edit: the Symfony best practices odpowiedz na większość moich pytań.

Mam kilka pytań dotyczących mojej aplikacji Symfony2.

Będzie miał frontend i backend, i będą używać wspólnego kodu (takiego jak wyświetlacz daty, paginator, niektóre często używane szablony, itp.).

Więc, stworzyłem jeden FrontendBundle i jeden BackendBundle, każdy zawierający na przykład swój układ. Pierwsze pytanie: czy jest to dobra praktyka tworzenia pakietów dla frontend i backend, czyli" ogólne " pakiety, które nie będą miały nawet kontrolera?

Drugie pytanie: czytałem w książce kucharskiej, że nie powinienem umieszczać moich układów w pakietach, ale w katalogu app/Resources/ views/. Mam już bazę.html.plik twig w nim, i zastanawiam się, czy nie powinienem umieścić swoje layouty tam też, jak frontend_layout.html.twig file?

Stworzyłem pakiet o nazwie RootBundle, który zawierałby wszystko, czego potrzebuje moja aplikacja w interfejsie i backendzie. Czy to dobrze ćwiczyć czy nie? Czy powinienem stworzyć dedykowany pakiet dla każdej proponowanej funkcjonalności, takiej jak PaginatorBundle, DateDisplayerBundle itp.? Dziwnie to brzmi, że mam jeden" różny " pakiet zawierający wszystko, czego Nie wiem, gdzie umieścić. Jak ty to robisz?

Author: Nanocom, 2011-11-04

2 answers

Nowe podejście

Po kilku miesiącach od napisania tej odpowiedzi moje podejście się zmieniło, więc dzielę się nim ze społecznością. Ta odpowiedź jest nadal dość popularna i może prowadzić nowicjuszy do podejścia, które moim zdaniem nie jest już najlepsze. Więc...

Teraz mam tylko jeden specyficzny dla aplikacji pakiet i nazywam go AppBundle. Było kilka problemów ze starym podejściem i oto niektóre z nich: {]}

  • Tworzenie wielu wiązki są uciążliwe. musisz utworzyć klasę bundle i kilka standardowych folderów dla każdego nowego pakietu, a następnie aktywować go i zarejestrować jego trasy, DI i tak dalej.

  • Niepotrzebny proces podejmowania decyzji hardcore. czasami po prostu nie możesz zdecydować, do którego pakietu należy dana rzecz, ponieważ jest używana przez więcej niż jeden pakiet. A po spędzeniu pół dnia i wreszcie podjęciu trudnej decyzji, gdzie go umieścić, znajdziesz to w kilka dni lub tygodni nie będziesz w stanie od razu powiedzieć, w którym pakiecie szukać tej rzeczy - ponieważ większość razy decyzja nie była oparta na czystej logice i trzeba było wybrać w oparciu o rzut monetą lub cokolwiek, czego używasz, aby przynieść wyższe moce o pomoc.

    Zasugerowałem użycie CommonBundle dla zwykłych rzeczy w przeszłości, ale robiąc to, będziesz musiał zrobić wiele niepotrzebnych refaktoringów przenoszących rzecz do i z CommonBundle w oparciu o to, ile lub kilka pakietów będzie tego używać później.

  • Pakiety specyficzne dla aplikacji są i tak współzależne. kiedy ludzie po raz pierwszy spotykają się z ideą wiązek, jedną z głównych myśli, która przechodzi przez ich umysły, jest coś w stylu " Yay! Kupię zestaw wielokrotnego użytku!"Ten pomysł jest świetny i nie mam nic przeciwko temu; problem w tym, że pakiety specyficzne dla aplikacji i tak nie są wielokrotnego użytku - są współzależne. Zapomnij o ponownym użyciu w to case.

  • Nie wiem, gdzie umieścić Behat funkcje i definicje kroków. ten problem jest związany z poprzednimi: musisz powtarzać te same bezmózgie ruchy dla każdej wiązki, a następnie podejmować hardcore decyzje.

    Kiedy zacząłem pisać funkcje Behata, po prostu nie mogłem zdecydować, gdzie umieścić wiele funkcji i definicji kroków, ponieważ należały do kilku pakietów na raz. Umieszczenie ich w CommonBundle wydawało się jeszcze gorsze, bo to ostatnia Paczka, w której bym tego szukała. Więc w końcu stworzyłem FeatureBundle do tego.

Przejście na pojedynczy pakiet rozwiązało wszystkie te problemy.

Widziałem też, że niektórzy ludzie mają oddzielny pakiet dla, powiedzmy, wszystkich Bytów. Nie podoba mi się to podejście i faktycznie sugerują trzymanie encji i innych specyficznych rzeczy nie Symfony2 z pakietów.

Zauważ jeszcze raz, że to nowe podejście dotyczy pakietów specyficznych dla aplikacji. Oficjalne dokumenty i inne miejsca są pełne świetnych porad, jak tworzyć pakiety przeznaczone do dzielenia się z innymi i ponownego wykorzystania w wielu projektach. piszę również pakiety tego typu . Ale po miesiącach pracy nad projektami Symfony2 dowiedziałem się, że istnieje różnica między pakietami przeznaczonymi do ponownego użycia a konkretnymi dla aplikacji - jedno podejście nie pasuje do wszystkich.

I, oczywiście, gdy zobaczysz coś wielokrotnego użytku pojawiającego się w konkretnym pakiecie aplikacji, po prostu wyodrębnij go, umieść w oddzielnym repo i zainstaluj jako sprzedawca.

Odkryłem również, że używam przestrzeni nazw o wiele bardziej aktywnie jako sposobu na logiczne partycjonowanie pakietu - zamiast tworzyć wiązki do tego i przechodzić przez te wszystkie problemy.

Stare podejście

Nie ma twardych i szybkich zasad ani srebrnych kul, ale podzielę się moim podejściem do robienia rzeczy-może to da ci wgląd lub dwa.

Po pierwsze, nie mam dwóch uniwersalne wiązki, takie jak FrontendBundle i BackendBundle. Zamiast tego, moje pakiety mają zarówno Kontrolery frontend i backend, widoki itp. Jeśli więc usunę wszystko z mojego UserBundle z wyjątkiem kontrolerów i widoków, jego struktura wyglądałaby tak:

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

Po drugie, mam CommonBundle które używam do rzeczy udostępnianych przez kilka pakietów:

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

My app/Resources/views/base.html.twig jest prawie taka sama jak w przypadku standardowej dystrybucji Symfony:

<!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>

Zarówno CommonBundle/Resources/views/layout.html jak i CommonBundle/Resources/views/Admin/layout.html rozszerzają app/Resources/views/base.html.twig. Szablony innych pakietów rozszerz jeden z tych dwóch układów, w zależności od tego, czy są one dla frontend lub backend. Zasadniczo, w ten sposób używam trzypoziomowego podejścia dziedziczenia .

Więc umieściłbym Twój wyświetlacz daty w CommonBundle. W zależności od złożoności może to być tylko szablon, makro lub gałązka rozszerzenie .

Paginacja jest częstym problemem, więc proponuję użyć jednego z istniejących Pakiety zamiast wymyślać na nowo koło-oczywiście jeśli spełnia Twoje potrzeby.

I tak, doskonale jest mieć pakiety bez kontrolerów, widoków itp.

 80
Author: Elnur Abdurrakhimov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Proponuję stworzyć DateDisplayerBundle i PaginatorBundle zamiast umieszczać ich powiązany kod w bardziej ogólnym pakiecie. Jest ku temu kilka powodów:

  • rola każdego pakietu jest bardzo jasna, a Ty wiesz, gdzie jest Twój kod.
  • dzielenie elementów funkcjonalności (wyświetlacz daty, paginator) między różnymi projektami jest prostsze, gdy masz oddzielne pakiety, w porównaniu z jednym ogólnym pakietem, który może być potrzebny do przycinania.

There ' s no hard rule mówiąc, że wiązki muszą mieć Kontrolery. Pakiety mogą zawierać dowolną kombinację logiki biznesowej, szablonów, kontrolerów i konfiguracji, ale nie ma ograniczeń co do tego, co można w nich przechowywać.

Z drugiej strony, jeśli twoja funkcjonalność nie jest zbyt skomplikowana, może nie gwarantować, że w ogóle jest zawarta w pakiecie. W tym przypadku możesz utworzyć bibliotekę /vendor dla niej. Symfony korzysta w ten sposób z wielu bibliotek (patrz np. Monolog i Doctrine.)

Jak dla twoje drugie pytanie, myślę, że powodem utrzymywania układów w app\Resources\views jest to, że jest to wygodny sposób, aby śledzić wszystkie swoje układy. Gdy masz projekt, który ma wiele pakietów, możesz stracić kontrolę nad tym, gdzie znajduje się określony układ. Ale jeśli trzymasz je wszystkie w jednej scentralizowanej lokalizacji, zawsze będziesz wiedział dokładnie, gdzie szukać. Podobnie jak w przypadku wielu rzeczy w Symfony2, nie jest to reguła, która jest osadzona w kamieniu. Możesz łatwo przechowywać swoje układy w pakiecie, ale nie sądzę, że jest to Zalecana Praktyka.

Jeśli chodzi o twoje pytanie dotyczące ogólnego pakietu Root, powiedziałbym, że w większości przypadków powinieneś unikać rootowania kilku różnych funkcji w jednym pakiecie. Zapoznaj się z moimi wcześniejszymi uwagami na temat utrzymywania konkretnych zestawów. Kiedy zaczÄ ... Ĺ 'em rozwijaÄ ‡ Symfony2, miaĹ' em problemy z okreĹ " leniem jaki kod powinien trafiÄ ‡ w jakim pakiecie. Nie tak przywykłem myśleć o programowaniu. Ale w końcu zaczynasz widzieć, jak poszczególne elementy układanki pasują, i że ułatwia określenie struktury wiązki.

 4
Author: Steven Mercatante,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-04 18:17:24