• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Symfony - pytanie dotyczące projektowania aplikacji (tworzenie obiektów)

Object Storage Arubacloud
0 głosów
212 wizyt
pytanie zadane 4 lipca 2020 w PHP przez XiverKi Bywalec (2,050 p.)
edycja 4 lipca 2020 przez XiverKi

Dzień dobry,

Chciałbym zapytać o rady, ludzi bardziej doświadczonych.
Tworze projekt w symfony i na etapie projektowania zrobiłem takie etap tworzenia i zapisywania obiektu do bazy.


Date wejściowe (kontroler) -> PrepareAndSave -> Prepare -> Creator

Działa to tak, że użytkownik wysyła jakieś dane na temat encji, do której odnosi się formularz na stronie.
Obiekt z danymi (właściwościami) przekazywana jest do metody prepareAndSave z serwisu PrepareAndSave.
W powyższej metodzie wykonywane są dwie akcje.

  1. Dane przekazywane są dalej do serwisu Prepare, który obrabia sobie w jakiś sposób dane i przekazuje je do Creatora, który z kolei tworzy już konkretny obiekt wskazanej Encji. Po jego utworzeniu i uzupełnieniu danymi obiekt zwracany jest z powrotem do metody prepareAndSave.
  2. Gotowy obiekt z punktu pierwszego przekazywany jest do entityManagera, który wrzuca go do bazy.

Czy takie rozwiązanie jest poprawne?

1 odpowiedź

0 głosów
odpowiedź 4 lipca 2020 przez Ehlert Ekspert (212,670 p.)

Widzę dużo problemów. 

  1. Dlaczego używasz tablic? Phpowy array to kontener na wszystko. Używaj obiektów. Jeśli pochodzą one z formularza, to mogą to być dto z publicznymi polami.
  2. Klasy mają niewłaściwe nazwy, nie powinny być czasownikami.
  3. Przyjęta nomenklatura nic nie mówi. Nie wskazuje z jakimi obiektami ma do czynienia. 
  4. PrepareAndSave z definicji ma więcej niż jedną odpowiedzialność. Albo się tam za dużo dzieje, albo dobierz odpowiednie nazewnictwo.
komentarz 6 lipca 2020 przez Ehlert Ekspert (212,670 p.)
Kilka refleksji na temat tego co poradziłem: ogólnie takie podejście to kroki w stronę może nie czystej, ale trochę "czystszej" architektury. Metody i kontrolery zaczynają chudnąć, taki kod staje się czytelniejszy. Łatwiej się go rozwija oraz testuje: jednostkowo i nie tylko. Są również problemy: generuje się dość znaczna ilość boilerplate'u. To co np w Django / Larvie zrobiłbyś w 8 linijkach, tutaj zrobisz w 6 plikach.

Warto przemyśleć: jeśli robisz mały projekt, bez perspektyw na rozwój, kilka encji, crud dla nich oraz admin, to nie ma co filozofować. Django albo Larva, dwa tygodnie i projekt z testami masz gotowy. Co innego jeśli rozwijasz system w którym będziesz siedzieć przez najbliższe dwa lata a klient jest poważny. Warto zadbać o komfort swojej pracy, jak i jakość tego co dowozisz.

Co do handlingu: w symfony, jak i w innych fw phpowych masz podejście safe to fail. Tworzysz walidację i formujesz kod tak, aby nie poleciał wyjątek. Jeśli już się tak stanie to user powinien dostać 500 (chyba że biznesowo nie jest to dopuszczalne), a Ty i tak się o tym dowiesz z logów czy monitoringu np New Relic, albo Blackfire.

Poszukaj w dokumentacji Symfony eventów które lecą przy exceptionach.
komentarz 6 lipca 2020 przez XiverKi Bywalec (2,050 p.)

Na pewno poczytam na temat tych eventów.

Chciałem jeszcze zahaczyć o to co było poruszone wcześniej mianowicie o metodę rejestracyjną. Posiadam w systemie jeszcze encje o nazwie server, która ma relacje do encji reprezentującej adres ip.

Dodałem, podobnie jak w przypadku uzytkownika, serwis serverRegisterer oraz metodę register, która rejestruje nowy server w bazie.

Server może (ale nie musi) posiadać adresy ip. Nie są one wymagane podczas dodawania go do bazy.

Rozwiązałem to w ten sposób:

    public function register(ServerRegistrationDto $registrationDto)
    {
        $ipAddresses = $registrationDto->serverIpAddresses;

        $server = $this->serverFactory->createServer($registrationDto);

        foreach ($ipAddresses as $address) {
            $address = $this->serverIpAddressFactory->createIpAddress($address);
            $server->addServerIpAddress($address);
        }

        $this->serverRepository->save($server);

        $this->readyServer = $server;
    }

Jest to poprawne? Czy powinien do tworzenia relacji stworzyć znowu, kolejną klasę i tam wyprowadzić ten proces?

komentarz 6 lipca 2020 przez Ehlert Ekspert (212,670 p.)

Zadaj sobie pytanie czy ta relacja jest kluczowa dla logiki którą implementujesz. Jeśli tak to przekazywałbym utworzone już encje adresów do konstruktora serwera poprzez factory.

Zamykanie logiki w encjach jest czymś mega użytecznym. Jeśli jakiś obiekt, w Twoim przypadku np user nie może istnieć bez username i hasła, to podawaj je przez konstruktor. Dzięki temu masz pewność że nikt nie utworzy tego obiektu bez podania tych wartości.

W powyższym kodzie martwi mnie to pole readyServer. frown

komentarz 6 lipca 2020 przez XiverKi Bywalec (2,050 p.)

co do readyServer to planowałem tam wrzucać gotowy obiekt server, który następnie mógłbym pobierać metodą getServer właśnie z tego serwisu ale po Twojej reakcji widzę, że to chyba zły pomysł. Lepiej byłoby w metodzie register dodać return, który zwracał będzie ten obiekt?

dobrze czyli nie jest niczym złym użycie konstruktora w encji, sądziłem, że to po prostu reprezentacja tabeli z bazy danych w przełożeniu na kod.

Czyli w encji Server musiałbym zaimplementować konstruktor, który przyjmować będzie te adresy, następnie w pętli za pomocą metody addIpAddress będzie dodawać je do kolekcji ipAddresses

Dobrze kombinuje?

komentarz 6 lipca 2020 przez Ehlert Ekspert (212,670 p.)

Dobrze. Robisz sobie lokalną tablicę którą zapełniasz stworzonymi ipkami i po pętli przekazujesz ją do utworzenia encji serwer.

ORM jest po to, aby wartości z tablic mapowane na konkretny byt miały swoje własne zachowania, stan, logikę. W przeciwnym wypadku można wszystko rozwiązać tablicami asocjacyjnymi. Vernon Vaugh takie zwykłe przekładanie pustych obiektów na tabele nazywał anemicznym modelem dziedziny. laugh

Lepiej byłoby w metodzie register dodać return, który zwracał będzie ten obiekt?

Oczywiście że tak. Skąd programista korzystający z tego serwisu ma wiedzieć że najpierw trzeba wykonać register a potem getServer.

Podobne pytania

0 głosów
3 odpowiedzi 650 wizyt
pytanie zadane 15 maja 2016 w PHP przez GaCeL Dyskutant (7,500 p.)
+2 głosów
1 odpowiedź 243 wizyt
pytanie zadane 29 października 2015 w PHP przez makoso Mądrala (7,380 p.)
0 głosów
0 odpowiedzi 197 wizyt
pytanie zadane 10 lipca 2022 w PHP przez MKolaj15 Bywalec (2,270 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...