[JAVA] Filtrowanie danych w pliku csv

Witajcie

Ostatnio napisałem dla siebie mały programik do wyciągania danych z pliku csv i zliczaniu kwoty.
W pliku csv zawarte są dane

“Data operacji”,“Data waluty”,“Typ transakcji”,“Kwota”,“Waluta”,“Saldo po transakcji”,“Opis transakcji”,"","","","",""

Program wyciągane dane, gdzie w typie transakcji zawarte jest słowo “Płatność”, następnie zlicza kwotę z tej transakcji.

Nie mam zastrzeżeń co do działania tego programu, ale jestem mocno początkujący w temacie programowania, poniżej zamieściłem link do mojego i proszę o jego ocenę, ewentualnie pokazanie gdzie popełniłem błędy w kodzie, które można poprawić :slight_smile:

main
https://pastebin.com/uXdiw7qA

klasa loaddata
https://pastebin.com/Vsjgc9Ds

1 polubienie

Wylistuję w punktach co bym poprawił lub zrobił inaczej, gdybyś miał pytania co do tego czemu się danej rzeczy czepiam lub jak to zrobić inaczej to pytaj. Nie będę się szczegółowo rozpisywał nad każdym z punktów bo nie sądzę by była taka potrzeba w każdym przypadku.

  1. main: szkoda, że zahardcodowałeś ścieżkę do pliku, mogłeś użyć do tego argumentów uruchomieniowych program, w tedy skompilowałbyś sobie program i podczas jego uruchamiania podawał za każdym razem ścieżkę - a może listę ścieżek do plików jakie należy przeliczyć :wink:

  2. Nazwy class LoadData oraz void loadData() trochę niefortunne i niewiele mówią do tego są prawie identyczne

  3. private float fileSize; nieużywana nigdzie właściwość

  4. Nigdzie nie używasz kolejnych właściwości, nadajesz im wartości, ale prywatną metodę i tak wywołujesz przekazując jej argumenty konstruktora. W niej też nie wykożystujesz prywatnych właściwości klasy.

    this.path = path;
    this.extension = extension;
    loadData(path, extension);
    
  5. new LoadData("c:\\temp\\plik",".csv"); rozszeżenie moim zdaniem jest częścią nazwy pliku i nie powinno być rozdzielone, ewentualnie może być parametr path i fileName, gdzie path to tylko ścieżka do katalogu gdzie jest plik o nazwie fileName

  6. String csvPath = path + extension; jak wyżej

  7. PrintStream fileStream = new PrintStream("c:\\temp\\filename.txt"); znów hardcodujesz ścieżkę, dodatkowo użyłbym raczej lokalizacji programu, a następnie plik ten skasował, chyba, że jest on wynikiem działania programu - nie wiem, nie prześledziłem działania kodu dokłądnie

  8. Złamana zasada jednej odpowiedzialności w funkcji void loadData(). Powinny być co najmniej 3 funkcje, jedna otwierająca plik, druga dokonująca obliczeń, trzecia zapisująca wynik. Dodatkowo wyświetlanie danych też wyodrębniłbym do osobnej funkcji, a nawet może klasy. Obecnie funkcja wykonuje 4 zadania, a powinno się dążyć tego by stosować zasadę jednej odpowiedzialności.

Ogólnie nie jest, źle. Program od strony kodu fajnie i mądrze napisany. Czepiałem się wszystkich możliwych szczegółów i detali bo o to prosiłeś :wink:. Widziałem znacznie gorzej napisany kod i nie uważam, żebyś miał się czego wstydzić.

EDIT:
Teraz to zauważyłem

  1. Pojedynczy rekord z pliku csv zrobiłbym jako osobną klasę tak by parsowanie odbywało się wewnątrz niej zamiast czegoś takiego

             String operation = csvRecord.get(0);
             String currency = csvRecord.get(1);
             String transaction = csvRecord.get(2);
             String amount = csvRecord.get(3);
             String description = csvRecord.get(6);
             String address = csvRecord.get(7);
    

Pewnie więcej rzeczy dałoby się poprawić, ale na tą chwilę to chyba tyle.

Troszkę rozbudowałem program, dodałem proste GUI. Teraz będę chciał pozbyć się hardcodowania i dodać możliwość wybierania pliku csv w GUI, oraz miejsca zapisu przesortowanego pliku.

Klasa Main
https://pastebin.com/UBpAttXg
Klasa LoadData
https://pastebin.com/Rx7ae977
Klasa PrintCSV
https://pastebin.com/8fmAxcjb
Klasa Alert
https://pastebin.com/rXmydHVT

Jest dużo lepiej, ale część wcześniej wymienionych rzeczy się powtórzyła.

Klasa nie powinna mieć nazwy w czasowniku (nie jestem polonistą poprawcie mnie), bardziej powinien to być rzeczownik, czyli DataLoader, loadData opisuje funkcję, a klasa nie jest funkcją tylko obiektem zawierającym jakieś funkcjonalności.

Unikaj też stosowania metod statycznych, może się to wydawać zbędne, ale w przyszłości może okazać się złym nawykiem.

2 polubienia