Mam moduł który działa tak:
Użytkownik(redaktor) importuje plik CSV z danymi głównie liczbowymi.
Z pliku czyta jeden moduł który dodaje te dane cache, żeby nie parsować za każdym razem, Jako cache mam: BD sql albo Redisa, nie ważne.
Skłaniam się do pierwszego rozwiązania, ponieważ nowe dane są wgrywane raz na miesiąc i je nadpisuje.
Mam 5 rodzajów plików CSV, i zrobiłem to tak jak na diagramie(https://www.draw.io/i/jskflDS) i w kontrolerze wywołuję:
... $form = $this->createCsvUploadForm(); $form->handleRequest($request); $this->validateFormSubmit(); $newFilePath = $this->moveUploadedData($form->get('file')->getData()); $csvFile = $this->getCsvFileObject($newFilePath); $csvType = $this->getType($cvFile); $parser = $this->getCsvParser($csvType); try { $parser->validate(); } catch (UserMessageException $e) { $this->addMessage($e->getMessage, self::MESSAGE_ERROR); $this->redirect(...); return; } $parser->parse(); $this->cacheData($parser);
...
Teraz mam 3 pytania:
1) Pierwsze pytanie dotyczy, gdzie umieścilibyście te klasy do obsługi pliku CSV, ja dodałem je do modelu, czy utworzylibyście serwis? Wg mnie jest to obsługa logiki biznesowej, ale mogę się mylić.
Klasa CsvFile jest wykorzystywana w kilku miejscach do generowania plików CSV z tablicy i odwrotnie.
Klasy Parserów są wykorzystywane tylko tutaj. Dane exportujemy z programu i jest to jakiś rodzaj API do importu do innej aplikacji.
2) Jeśli coś jest nie tak, tzn jakiś wiersz jest niepoprawny, jakiś email zły, liczby są niepoprawne to metoda Parser::validate() rzuca wyjątek z informacją co jest nie tak. Nie miałem pomysłu jak to rozwiązać, myślałem nad zwróceniem tablicy z błędami, ale wg mnie chyba lepiej wykorzystać wyjątek, bo jest to jakiś rodzaj sytuacji wyjątkowej... Jak wy byście to zrobili?
3) Przed refaktoryzacją kodu akcji - kod miał około 250 lini, czy lepiej zostawić if'y w akcji np tak:
if ($request->isMethod('POST')) { $form->submit($request->request->get($form->getName())); if ($form->isSubmitted() && $form->isValid()) { // perform some action... return $this->redirectToRoute('task_success'); } }
czy rozbić to na metody takie jak zrobiłem, bez zagnieżdżeń? Gdzie jest granica, jak bardzo rozbijać funkcje?
Przyznam, że czasem zdarzy mi się napisać jednolinikowce: takie jak:
private function isOpened() { return $this.status === self::STATUS_OPENED; }
Czasem dochodzi tez do sytuacji, że klasa ma po 20/30 metod prywatnych, często krótkich, które są używane w 4/5 metodach publicznych. Co wy robicie w takich przypadkach?