Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [Symfony2][Symfony]Odchudzanie kontrolerów
athabus
post
Post #1





Grupa: Zarejestrowani
Postów: 898
Pomógł: 48
Dołączył: 2.11.2005
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Kolejne moje pytanie z serii "jak to poprawnie zorganizować w Symfony". Otóż napotykam na problem, że przy bardziej rozbudowanej aplikacji moje kontrolery zaczynają bardzo "puchnąć". Przykład z dzisiaj - interakcje miedzy różnymi Entity.

Załóżmy, że buduję generator ćwiczeń na siłowni, którego celem jest wygenerowanie planu na dany dzień, z określonymi parametrami.

Moje Entity wyglądają tak:

- ćwiczenie - to bazowe ćwiczenia typu pompki, podciąganie na drążku etc z np. przypisanymi trudnościami w skali 1-5
- zadanie - zadanie to wykonanie pewnej ilości ćwiczeń - np. 5 pompek
- seria - grupa zadań do wykonania (czyli np. 5x pompki, 10x podciąganie) itd.
- plan - ilość serii do wykonania

I teraz załóżmy, że piszę generator, który ma wylosować taki plan, gdzie zawodnik nazbiera łącznie np 100punktów za wykonane ćwiczenia. I tu się rodzi pytanie gdzie umieścić algorytm losowania takiego planu - czyli np. mógłby on wyglądać tak:
- wybierz losowo 3 ćwiczenia -> dobierze ilość powtórzeń tak aby seria miała 25 punktów -> stwórz 4 takie serie i zapisz je jako plan na dzisiaj

Można to zrobić w kontrolerze, ale wtedy taki kontroller strasznie puchnie. W demo_app do symfony właśnie tak to robią, ale tam mają bardzo prostą aplikację, która ogranicza się do CRUD, więc logiki tam praktycznie nie ma.

Można by zrobić to w modelu, ale w teorii z tego co zrozumiałem, to model nie ma odpowiadać za logikę tylko odczyt/zapis danych, a w tym przypadku taki entity Plan musiałby odczytywać/zapisywać/analizować dane z innych Entity, czyli zaczyna się robić spaghetti code.

Gdzieś widziałem, że ktoś postulował przerzucanie wszystkiego do services i wstrzykiwanie do nich wszystkich potrzebnych rzeczy typu ObjectManager itd. Czyli przykładowo robimy services "planCwiczen" i w nim znajduje się cała logika wyboru ćwiczeń, zapisywania wszystkiego w bazie itd. a w kotrolerze mamy tylko cos w stylu $this->get('planCwiczen')->createWorkout(). Pytanie tylko czy Services były tworzone z myślą do przechowywania całej logiki aplikacji?

Jak wy sobie z tym radzicie? Gdzie trzymacie tą część kodu odpowiedzialną za algorytm działania?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Crozin
post
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Na początek wyjaśnijmy kilka podstawowych rzeczy:
1. Model to nie jest wybieranie/zapisywanie danych z/do bazy danych! Model to w kontekście MVC cała warstwa aplikacji odpowiedzialna za przetwarzanie danych. Czyli będziesz miał tam zarówno wyciąganie danych z bazy (DAO) jak i ich przetwarzanie (generator planu ćwiczeń).
2. Jedna klasa/obiekt nie powinna zajmować się wieloma rzeczami. Jeżeli jeden obiekt odpowiedzialny jest za wyciąganie danych nie powinien on już skupiać się na ich przetwarzaniu.

Wracając do pytania. Powinieneś utworzyć sobie właśnie taką klasę jak GeneratorPlanuĆwiczeń, która może mieć metodę wygeneruj(), która na podstawie jakiś tam parametrów zwróci obiekt PlanĆwiczeń, który to zaś będzie zawierać w sobie Serie, Zadania i Ćwiczenia. Jeżeli generator potrzebuje do swojego działania jakiś zewnętrznych zależności powinny zostać one przekazane w konstruktorze (stąd jak najbardziej można skorzystać z Symfonowego kontenera w celu tworzenia takiego obiektu). Generator to generator, a nie "zapisywator", więc sam zapis obiektu PlanĆwiczeń powinien być zrealizowany przez inny obiekt. W efekcie kontroler mógłby wyglądać tak:
  1. class WorkoutController
  2. {
  3. /** @var SomeWorkoutGenerator */
  4. private $workoutGenerator;
  5.  
  6. /** @var WorkoutStore */
  7. private $workoutStore;
  8.  
  9. public function __construct(...) { ... }
  10.  
  11. public function generateAction(Request $request)
  12. {
  13. $workoutPlan = $this->workoutPlanGenerator->generate($request->query->get('pointsLimit', 25));
  14.  
  15. // jeżeli potrzebujesz możesz jeszcze dostosować plan, np.:
  16. $workoutPlan->setOwner($this->getUser());
  17.  
  18. $this->workoutStore->store($workoutPlan);
  19.  
  20. return new Response('Nowy plan ćwiczeń został wygenerowany i zapisany.');
  21. }
  22. }
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 12.10.2025 - 23:26