2013-06-13 13 views
16

Mam pytanie dotyczące najlepszych praktyk w Symfony 2. Przepraszam, jeśli jest to trochę niejasne i subiektywne. Zgaduję, że mogę podsumować moje pytanie jako:Najlepsze praktyki w Symfony. Czy zapytania powinny znajdować się w repozytoriach lub usługach?

"Czy repozytoria zawsze są odpowiednim miejscem na zapytania?".

W tej chwili umieszczam większość moich zapytań doktrynalnych w repozytoriach jednostek. Większość moich działań kontrolera wykonuje typowe czynności, takie jak zapytanie o encję lub kolekcję podmiotów, wyrzuca wyjątek lub przekierowanie w zależności od wyniku, w przeciwnym razie aktualizuje jeden lub więcej podmiotów. Większość działań jest bardziej złożona, niż można zrobić wydajnie za pomocą zapytań standard -> find, -> findBy itp. Większość wymaga złączeń. Kiedy kwerenda zawiera wiele elementów, czasami nie jestem pewien, które repozytorium powinno nawet wejść. Domyślam się, że istnieje element główny kwerendy, ale ... czasami dane z połączonych encji są ważniejsze i trafniejsze, więc czuje się źle umieścić go w repozytorium jednostki głównej.

To działa dobrze, ale zazwyczaj mam w repozytoriach wiele niemal identycznych, ale nieco odmiennych zapytań. Wymyślanie nazwisk i śledzenie tego, co każdy robi, może stać się mylące i nużące. Większość tych zapytań jest używana tylko przez jedno lub dwa (często rzadko używane) działania kontrolera w tym samym kontrolerze. Czuję, że zaśmiecam moje repozytoria zbyt dużą ilością specjalistycznych, rzadko używanych rzeczy.

Wygląda na to, że wszystkie najprostsze czynności należy zamknąć w obiekcie lub usłudze. Zacząłem więc wykonywać wiele moich zapytań bezpośrednio w usłudze, a nie w repozytorium. Łatwo spojrzeć na akcję w jednym miejscu. Czy to jest dobra praktyka?

+1

Kontroler powinien być naprawdę cienką warstwą między światem aplikacji a światem http i polecam zawsze umieszczać zapytania w repozytoriach. –

Odpowiedz

9

Twoje pytania powinny być przechowywane w jednostce repozytoria a nie w sterownikach, aby móc ponownego wykorzystania je z łatwością.

Tym właśnie są repozytoria. Zapewnienie wielokrotnego użytku dla zapytań do bazy danych.

Istnieje jednak kilka sytuacji, w których można poprawić wszystkie zapytania w repozytorium, szczególnie jeśli chodzi o filtrowanie, gdy szybko może być potrzebnych wiele zapytań.

Benjamin Eberlei (twórca Doctrine) uważa 5 publicznych metod w klasie za w porządku, a 10 za dość duże. Niedawno opublikował na swoim blogu interesujący artykuł o nazwie "On Taming Repository Classes in Doctrine".

Częściowo lubię filtrowalne rozwiązanie cechy repozytorium autorstwa KnpLabs w ich DoctrineBehaviors.

cechy sprawiają, że testowanie trudniej, ale można mieć czystsze i łatwiej utrzymać repozytorium ... gdzie należy zachować zapytania.

+2

Dzięki za linki, oba są interesujące. Nie miałem zamiaru umieszczać zapytań w kontrolerach. Po prostu szukam sposobu na uniknięcie wzdęcia moich repozytoriów wieloma podobnymi, ale nie do końca podobnymi zapytaniami o podobnych, ale nie do końca tych samych nazwach. – tetranz

9

Możesz zrobić coś pomiędzy.

Zdefiniuj usługę:

blog.post_manager: 
    class: Acme\BlogBundle\Entity\Manager\PostManager 
    arguments: 
     em: "@doctrine.orm.entity_manager" 
     class: Acme\BlogBundle\Entity\Post 

następnie utworzyć klasę Manager:

use Doctrine\ORM\EntityManager; 
use Doctrine\ORM\EntityRepository; 

class PostManager 
{ 
    protected $em; 

    protected $repo; 

    protected $class; 

    public function __construct(EntityManager $em, $class) { 
     $this->em = $em; 
     $this->class = $class; 
     $this->repo = $em->getRepository($class); 
    } 

    public function get($id) 
    { 
     return $this->repo->findById($id); 
    } 
} 

W ten sposób można jeszcze zostawić zapytań do której należą, w repozytoriach, pozwalając jednocześnie kod ponownego wykorzystania przez usługa menedżera, która może być używana w taki sposób w dowolnym kontrolerze:

$this->container->get('blog.post_manager')->get(1); 

Od czasu Ice zajmuje się wstrzykiwaniem klasy i podmiotu do klasy Managera, dzięki czemu kontroler jest cieńszy i lepiej odciąga go od modelu.

+1

Zajęcia z klas +1 to dobra wskazówka, choć prawdziwym pytaniem było, gdzie należy przechowywać swoje zapytania - które powinny być prawie zawsze repozytorium. Klasa menedżerska zapewnia korzyści wynikające z abstrahowania różnych sposobów uzyskiwania dostępu do bazy danych. możesz mieć jedną klasę menedżera za pomocą repozytorium jednostek, inną za pomocą repozytorium dokumentów innego przy użyciu zupełnie innego zaplecza pamięci. o ile wszystkie implementują ten sam interfejs, można je wymieniać w kontrolerze. W ten sposób np. FOSUserBundle obsługuje doktrynę orm, odm i propel :) – nifr

+1

"W ten sposób nadal możesz pozostawić zapytania, do których należą, w repozytoriach, [...]" –

+0

ah to jest ukryte, przepraszam było szybkie czytanie :) – nifr

Powiązane problemy