• 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)

VPS Starter Arubacloud
0 głosów
195 wizyt
pytanie zadane 4 lipca 2020 w PHP przez XiverKi Obywatel (1,920 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,630 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,630 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 Obywatel (1,920 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,630 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 Obywatel (1,920 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,630 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 591 wizyt
pytanie zadane 15 maja 2016 w PHP przez GaCeL Dyskutant (7,500 p.)
+2 głosów
1 odpowiedź 238 wizyt
pytanie zadane 29 października 2015 w PHP przez makoso Mądrala (7,380 p.)
0 głosów
0 odpowiedzi 192 wizyt
pytanie zadane 10 lipca 2022 w PHP przez MKolaj15 Bywalec (2,270 p.)

92,455 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...