Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [Symfony][OOP]Gdzie umieścić złożoną logikę - kilka klas zgodnych z SOLID?
Forum PHP.pl > Forum > PHP > Frameworki
mathieus
Witam,

mam kilka klas połącząnych, załóżmy, według wzorca Mediator,
który skłąda się z conajmniej dwóch interfejsów i 4 klas.
Jak wiadomo, standardem jest: jedna klasa, jeden plik.
Gdzie umieścić te pliki i jak łączyć klasy zgodnie ze standardami?:

  • w tym samym katalogu co kontrolery?
  • w osobnym podkatalogu katalogu src?
  • jako service? jak wtedy ogarnąć kilka klas?
  • jako biblioteka? z tym to zupełnie nie wiem jak - bardzo byłbym rad za wskazówki (np. link do opisu w internecie)...


z góry dziękuję za wskazówki.
Pozdrawiam
LowiczakPL
Mediator to serwis, który jest np. w folderze src/Service, ja tak grupuję serwisy.

Mam projekty, które mają sporo serwisów/kontrolerów, więc nie przejmuj się ilością plików dasz radę to ogarnąć.

U mnie często klasa ma swoją unikalną nazwę z sufixem zależnym od tego czym jest, czyli np:

src/Service/MediatorService.php
src/Interface/MediatorInterface,php
src/Abstract/MediatorAbstract.php
src/Helper/MediatorHelper.php
src/Manager/MediatorManager.php
src/Event/MediatorEvent.php

Taki sufix ułatwia mi DI i łatwiejsze rozeznanie się w kodzie.

Cytat(mathieus @ 9.01.2021, 11:12:34 ) *
mam kilka klas połącząnych, załóżmy, według wzorca Mediator,
...
Gdzie umieścić te pliki i jak łączyć klasy zgodnie ze standardami?:


Piszesz że masz połączone, a jednocześnie pytasz się jak łączyć?

Chodzi Ci o to jak wstrzyknąć je do Serwisu a następnie jak wywołać serwis w kontrolerze?
mathieus
Bardzo dziękuję za odpowiedź.

Mediator podałem jako przykład na którym się wzorowałem. Chodzi o dowolny system klas. To co mam to nie jest mediator, tylko taki schemat (pewnie to nie żaden wzorzec):

Kolejność działań (wraz z kodem) jest opisana tutaj:
Link do aplikacji (github.pl)
opis wywołań jest w podkatalogu Tests.

Cytat(LowiczakPL @ 11.01.2021, 22:18:39 ) *
src/Service/MediatorService.php
src/Interface/MediatorInterface,php
src/Abstract/MediatorAbstract.php
src/Helper/MediatorHelper.php
src/Manager/MediatorManager.php
src/Event/MediatorEvent.php

Taki sufix ułatwia mi DI i łatwiejsze rozeznanie się w kodzie.

jeśli się da, to spróbuję dać te podkatalogi do podkatalogu src/Service lub jeszcze innego.

Cytat(LowiczakPL @ 11.01.2021, 22:18:39 ) *
Piszesz że masz połączone, a jednocześnie pytasz się jak łączyć?

Mam połączone ze sobą, ale bez Symfony. W czystym PHP na klasach, z Twig'iem.
Cytat(LowiczakPL @ 11.01.2021, 22:18:39 ) *
Chodzi Ci o to jak wstrzyknąć je do Serwisu a następnie jak wywołać serwis w kontrolerze?

dokładnie. W ciągu kilku dni (obecnie nie mam zbytnio czasu) postaram dostarczyć do oceny rozwiązanie według Twoich wskazówek, ale czuję że będę miał jeszcze pytania (jeśli nię męczę za bardzo...).

jeszcze raz dziękuję i pozdrawiam.
LowiczakPL
No więc w Symfony gdy stworzysz sobie kontroler z akcjami.

Potrzebny jest serwis, który powinieneś wstrzyknąć w metodzie nigdy w konstruktorze kontrolera (co innego w serwisie, w którym możesz robić to bezpośrednio w konstruktorze).

Taki uproszczony przykład skorzystania z serwisu i repozytorium oraz wstrzykiwanie serwisu i repozytorium do metody, czyli to Twoje łącznie no chyba że o co innego chodziło.

Metoda Kontrolera:
  1. /**
  2.   * @Route("/sell/{name}/{quantity}", name="sell", methods={"POST"})
  3.   *
  4.   * @param CPocketRepository $repository
  5.   * @param CPocketService $service
  6.   * @param string $name
  7.   * @param int $quantity
  8.   */
  9. private function sell(CPocketRepository $repository, CPocketService $service, string $name, int $quantity): void
  10. {
  11. $product = $repository->findOneByName($name);
  12. $service->sell($product, $quantity);
  13. $em = $this->getDoctrine()->getManager();
  14. $em->persist($product);
  15. $em->flush();
  16. }


Metoda serwisu CPocketService:
  1. private function sell(CPocket $cPocket, int $quantity): void
  2. {
  3. $cPocket->setQuantity($cPocket->getQuantity() + 99);
  4. }
mathieus
Znalazłem wczoraj w nocy czas, więc zrobiłem wersję pod Symfony:
(github) Trade Wars - to co poprzednio, ale jako serwis w symfony

Cała "zawartość" mieści się w podkatalogu "src/Service" oraz w pliku "tests/indextTest.php".
src/Service
- Entities
- - - - Item.php
- - - - Product.php
- Interfaces
- - - - IMarket.php
- - - - IPocket.php
- Logic
- - - - CMarket.php
- - - - CPocket.php
- Round.php

Pierwszy test działa - czyli działa inicjacja gry i kupowanie.

Drugi test nie działa, gdyż najwyraźniej nie zapamiętuje $_SESSION. Być może skorzystam z tego co podesłałeś, czyli będę wrzucał do bazy danych, chociaż ta zasady tej gry tego nie wymagają. Prawdopodobnie powalczę jeszcze z session...

dzięki za kontynuowanie tematu

PS. teraz się zastanawiam, czy moje entities nie są w złym miejscu, ale jeżeli nie doctrine, to nie wiem gdzie... może doctrine jest koniecznością - jutro na spokojnie przemyślę.
LowiczakPL
Tworząc nowy projekt Symfony zasugerował Ci w jakich folderach masz tworzyć klasy, masz w src folder Entity on jest na Encje.

Wcześniej rozpisałem Tobie gdzie jakie pliki mają trafiać a Ty wrzucasz wsio do jednego GARA czyli do foldery Service

folder src/Service zawiera tylko Klasy Serwisów

Symfony oferuje generatory, nie musisz NIC programować, Symfony zrobi to za Ciebie, ty tylko musisz wiedzieć jakie pola chcesz mieć w aplikacji.

Jak już to Symfony zrobi za Ciebie możesz sobie to dopasować do Swoich potrzeb ale na start proponuję skorzystać z generatorów, przeanalizować kod i na podstawie kodu generatora możesz klepać kod ręcznie co moim zdaniem jest niepotrzebne jak już wiesz na czym to polega.

Ja jadę cały czas na generatorach jako bazie kodu, resztę dopisuje ręcznie.

Dodaj sobie generatory do aplikacji

Kod
composer require make -dev


Generator Encji to

Kod
php bin/console make:entity


Generator poprowadzi Cię za rączkę

Jeśli chcesz sprawdzić jakie są generatory to służy do tego komenda:

Kod
php bin/console make


Ale najpierw zrób sobie Qlturalne Encje za pomocą generatora, od razu będziesz miał wygenerowane Repozytoria to Encji to dzieje się z automatu. Repozytorium Encji jest NIEZBĘDNE bez tego nie wyobrażam sobie korzystania z apki.

proponuje zmienić nazewnictwo
nie IPocket tylko PocketInterface
nie CPocket tylko PocketService

Poza tym wszystkie klasy z jakich korzystasz dodaj do use

jest

  1. <?php
  2.  
  3. namespace App\Service\Logic;
  4.  
  5. use App\Service\Entities\Item;
  6.  
  7. class CPocket implements \App\Service\Interfaces\IPocket



  1.  
  2. powinno być
  3.  
  4. <?php
  5.  
  6. namespace App\Service\Logic;
  7.  
  8. use App\Service\Entities\Item;
  9. use App\Service\Interfaces\IPocket;
  10.  
  11. class CPocket implements IPocket


pomijam to że nie są to odpowiednie foldery
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.