Obliczanie EAN - jak zrobić to lepiej ?

Obliczanie EAN - jak zrobić to lepiej ?
AW
  • Rejestracja:ponad 9 lat
  • Ostatnio:około 3 lata
  • Postów:19
0

Celem zadania jest napisanie funkcji sprawdzającej, czy podany tekst jest kodem kreskowym EAN-13
lub EAN-8.
Na wejściu funkcji są dwa parametry:

  • wejściowy kod kreskowy: parametr tekstowy
  • rodzaj kodu kreskowego - parametr numeryczny: 1 dla EAN-8, 2 dla EAN-13.
    Niektóre towary (np. czasopisma) mają dodatkowe kody (tzw. add-on'y) - należy mieć na uwadze, że
    skaner może dokleić je bezpośrednio do właściwego kodu kreskowego (np. dla towaru o kodzie
    "6920702707721" oraz add-on’ie "12" na wejściu możliwy jest ciąg "692070270772112"). Należy
    założyć, że add-on'y mogą występować zarówno dla kodów EAN-8 jaki i EAN-13.
    Należy mieć na uwadze, że niektóre skanery kodów kreskowych mogą wycinać z kodu kreskowego
    pierwsze wiodące zero (np. zamiast kodu "0075678164125" przesyłają "075678164125").
    Na wyjściu funkcja powinna zwracać prawidłowy kod kreskowy (o długości 8 lub 13 znaków) bez
    ewentualnego add-on'u.
    Ewentualne błędy w danych wejściowych powinny być sygnalizowane wyjątkami.
Kopiuj
public class EAN {
    public boolean eanOk = false;

    private String howLongIsEan(String ean) {
        int checkLongEan = ean.length();

        if (checkLongEan == 7 || checkLongEan == 12) {
            ean = "0" + ean;
        }
        if (checkLongEan == 9 || checkLongEan == 14) {
            ean = "0" + ean;
            ean = ean.substring(0, ean.length() - 2);
        }
        if (checkLongEan == 10 || checkLongEan == 15) {
            ean = ean.substring(0, ean.length() - 2);
        }
        return ean;
    }

    private String checkEanNumberOfControl(String ean) {
        ArrayList<Integer> codeIntList = new ArrayList<>();

        String finalEan;
        int sumOddNumbers = 0;
        int sumEvenNumbers = 0;
        int resultOddPlusEven = 0;
        int saveLastNumber = 0;

        String eanText = howLongIsEan(ean);
        int eanIsLong = eanText.length();

        if (eanIsLong == 8 || eanIsLong == 13) {
            for (int i = 0; i < eanText.length(); i++) {
                codeIntList.add(Integer.parseInt(String.valueOf(eanText.charAt(i))));
            }

            saveLastNumber = codeIntList.get(codeIntList.size() - 1);
            codeIntList.remove(codeIntList.size() - 1);
            Collections.reverse(codeIntList);

            for (int i = 0; i < codeIntList.size(); i++) {
                if (i % 2 == 0) {
                    sumOddNumbers += codeIntList.get(i) * 3;
                } else {
                    sumEvenNumbers += codeIntList.get(i);
                }
            }
            resultOddPlusEven = sumOddNumbers + sumEvenNumbers;
        }

        int modulo = resultOddPlusEven % 10;

        if (modulo == (10 - saveLastNumber) && saveLastNumber != 0) {
            eanOk = true;
            finalEan = eanText;
        } else if (saveLastNumber == 0 && modulo == saveLastNumber) {
            eanOk = true;
            finalEan = eanText;
        } else {
            eanOk = false;
            finalEan = eanText;
        }
        return finalEan;
    }

    public void checkEan(String ean, int number) {
        String finalEan = checkEanNumberOfControl(ean);
        try {
            int eanSize = finalEan.length();
            if (eanOk) {
                if (number == 1 && eanSize == 8) {
                    System.out.println("Podany kod ean-8 jest poprawny: " + finalEan);
                } else if (number == 2 && eanSize == 13) {
                    System.out.println("Podany kod ean-13 jest poprawny: " + finalEan);
                } else {
                    System.out.println("Podałeś nieprawidłowy kod ean: " + finalEan);
                }
            } else {
                System.out.println("Podałeś nieprawidłowy kod ean: " + finalEan);
            }
        } catch (IllegalArgumentException e) {
            System.out.println("Podałeś nieprawidłowy kod ean" + finalEan);
        }
    }
}

W odpowiedzi dostałem taką odpowiedź "wyliczenie sumy kontrolnej dla wielu przypadków, a później sprawdzanie długości kodu EAN dla 8 i 13 znaków - rozwiązanie trudne do zrozumienia". Moje pytanie brzmi jak mogę go poprawić by kod był zrozumiały ?

Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 6 godzin
  • Postów:1875
2

Nie czytałem całości, bo czas, ale jest trochę do poprawy:

  1. Po co to pole w klasie? Jeśli to jest Value Object, to spoko, ale daj też sam surowy ean. To pole na pewno nie powinno być publiczne -> enkapsulacja.
  2. howLongIsEan zwraca ean, sygnatura metody sugeruje, że jest to String -> Integer
  3. Więcej małych dobrze nazwanych funkcji. Do tego nazewnictwo zmiennych na tyle na ile się da w takim kodzie bądź co bądź "matematycznym".

”Engineering is easy. People are hard.” Bill Coughran
edytowany 1x, ostatnio: Charles_Ray
CS
  • Rejestracja:ponad 6 lat
  • Ostatnio:3 dni
  • Postów:296
0

Do tego co napisał @Charles_Ray dodałbym jeszcze: unikaj else i pisz kod konsekwentnie np.:

Kopiuj
if (eanOk) {
 if (number == 1 && eanSize == 8) {
   System.out.println("Podany kod ean-8 jest poprawny: " + finalEan);
  } else if (number == 2 && eanSize == 13) {
   System.out.println("Podany kod ean-13 jest poprawny: " + finalEan);
  } else {
   System.out.println("Podałeś nieprawidłowy kod ean: " + finalEan); //czyli ean nie jest ok?!
 }
 } else {
    System.out.println("Podałeś nieprawidłowy kod ean: " + finalEan);
}
Kopiuj

Jeśli spełniony jest warunek głównego `if`-a, że `eanOk` to co robi wewnątrz tej instrukcji drukowanie komunikatu, że jednak ean jest nieprawidłowy?!
edytowany 1x, ostatnio: cs

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.