Gyakorlati alapok III.

Magasszintű objektumorientáltság egy validált prímszámtömbön keresztül


Ebben a fejezetben megpróbáljuk magasszintű objektumorientált elveinket egyetlen projektbe gyömöszölni. Úgy tűnik, hogy ennek többé-kevésbé sikerülnie kell, hiszen már osztályszinten, interfészek és getter-setter függvények hiperaktív ismeretével gondolkodunk. (A jelen projektben egyedül öröklődés nincs.)

 

Maga a feladat egészen jellegtelen: alkossunk egy teljesen validált prímszámtömböt, méretét a felhasználó adja meg, az értéktartomány pedig legyen 0 és 100 között. Ekkor a következő számsorból várjuk a felhasználó által meghatározott x mennyiségű prímszámot:


2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97


A feladat nyilván lehetne más is, így tehát már nem is az számít, hanem az objektumorientált elvek következetes, “gyönyörűségesen izgalmas” kibontása. Nézzük is meg ezeket!

Mindenekelőtt az okosan meghatározott funkciókat osztályokba és interfészekbe kell szerveznünk. Ezek a következők lehetnek:

Messageable
Ez az interfész (amelynek nevét programozási konvenció szerint szokás az -able utótaggal bővíteni) “elvi” szinten meghatározzák azon üzeneteket, amelyek a projekt során egyáltalán előfordulhatnak. Az interfész egyúttal mindig egy múltbéli üzenet is jövőbéli programozóknak, hiszen azt nekik kötelező kidolgozniuk. Ezen projekt során háromféle üzenet merülhet fel:

String messageError(); - hibaüzenet
String messageInput(); - üzenet adatbekéréskor
String messageInformation(); - egyéb információs üzenet

Validable
Ez az interfész (amelynek nevét programozási konvenció szerint szokás az -able utótaggal bővíteni) “elvi” szinten meghatározzák azon ellenőrző metódusokat, amelyeket a projekt során a bemeneti adatokon kötelező elvégezni. Ez kétféle lehet:

boolean isValid(int number); - prímszám-tulajdonság ellenőrzése
boolean isValid(int number, int min, int max); - értéktartomány ellenőrzése

ValidatorPrime
Ez az osztály a Validable és Messageable interfészek ráeső konkrét, specifikus feladatait implementálja, de csakis azokat, amelyek a prímszám (prime) validálásával kapcsolatosak.

ValidatorRange
Ez az osztály a Validable és Messageable interfészek ráeső konkrét, specifikus feladatait implementálja, de csakis azokat, amelyek az értéktartomány (range) validálásával kapcsolatosak. Érdekesség, hogy emiatt az egyik metódus nem került kidolgozásra…

@Override
public boolean isValid(int number) {
    return false;
}


...hiszen annak implementációja a ValidatorPrime osztályban található. Nem probléma ez, mert bár a kódnak kötelezően tartalmaznia kell, másként hibaüzenetet kapunk, ám ha nem történik rá hivatkozás, akkor nyilvánvalóan nem fog gondokat okozni.

UserInputHandler
Ez az osztály begyűjti, ellenőrzi, validálja az összes bemeneti adatot a felhasználótól, valamint a ValidatorPrime és a ValidatorRange osztálytól és ha azok megfelelőek, akkor átadja a végső összegzésre a Main osztálynak. Ebben a minőségében tehát nem is lép tovább, amíg az adatok rosszak. Tapasztaltabbak azonban észrevehetnek +1 validálást: a felhasználó inkorrekt számbeadása esetén try-catch blokk felhasználásával kivétel elkapása történik:

try {
    inputStringRange = scanner.nextLine();
    setNumber(Integer.parseInt(inputStringRange));
    }
    catch (NumberFormatException e) {
        System.out.println(validatorRange.messageInformation());
        continue;
}


A rutint ugyan lehetett volna külön (kivétel)osztályba is tenni, ám ebben a verzióban mégis benne hagytam, mert:

Main
Az osztály main() főprogramja egyfajta végső futtatását végzi el a kódnak és csupán 1 osztályt példányosít, a UserInputHandler osztályt. Ebben a minőségében a végső összesítést hajtja végre.

A futtatás után a következőket vehetjük észre:
a kód nem rendezi a prímszámtömb elemeit (sort) és engedi a számredundanciát (ugyanazon prímszám többször is beírva). Ezek alapjában véve nem problémák, mert ezekről nem szóltak a projektkövetelmények, de esetleg a Tisztelt Olvasó házi feladatként megpróbálhatja ezeket megoldani.


Nézzük meg a futtatható Java-kódot:
 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

Messageable.java

public interface Messageable {
    String messageError();
    String messageInput();
    String messageInformation();
}
 

Validable.java


public interface Validable {
    boolean isValid(int number);
    boolean isValid(int number, int min, int max);
}

 

ValidatorPrime.java

public class ValidatorPrime implements Validable, Messageable {

@Override
public boolean isValid(int number){
    boolean valid = false;
    if (number == 1 || number == 0) {
        return valid;
    }
    else
    for(int j = 2; j <= Math.sqrt(number); j++){
        if (number % j == 0) {
            return valid;
            }
    }
    valid = true;
    return valid;
}

@Override
public boolean isValid(int number, int min, int max){
    boolean valid = false;
    if(number >= min && number <= max) {
        valid = true;
        return valid;
    }
    return valid;
}

@Override
public String messageError() {
    return "A szam nem primszam! Probalja ujra!";
}

@Override
public String messageInput() {
    return "Kerem adja meg a szam(okat) (1 és 100 kozott)!";
}

public String messageInformation() {
    return "A muvelet vagy a szam nem ervenyes! Probalja ujra!";
    }
}

 

ValidatorRange.java

public class ValidatorRange implements Validable, Messageable{

@Override
public boolean isValid(int number, int min, int max){
    boolean valid = false;
    if(number >= min && number <= max) {
        valid = true;
        return valid;
    }
    return valid;
}

@Override
public String messageError() {
    return "Kerem, hogy csakis a tartomanyon belul adjon meg szamokat! Probalja ujra!";
}


@Override
public String messageInput() {
    return "Kerem adja meg, hany szamot szeretne beadni (1 és 10 kozott)!";
}

@Override
public String messageInformation() {
    return "A muvelet vagy a szam nem ervenyes! Probalja ujra!";
}

@Override
public boolean isValid(int number) {
    return false;
    }
}
 

UserInputHandler.java

import java.util.Scanner;

public class UserInputHandler {
    private Scanner scanner = new Scanner(System.in);

    private int number = 0;

public int getNumber() {
    return number;
}

public void setNumber(int number) {
    this.number = number;
}

public int readInputNumberForArray() {
    ValidatorRange validatorRange = new ValidatorRange();
    String inputStringRange;
    do {
        System.out.println(validatorRange.messageInput());
        try {
            inputStringRange = scanner.nextLine();
            setNumber(Integer.parseInt(inputStringRange));
        }
        catch (NumberFormatException e) {
            System.out.println(validatorRange.messageInformation());
            continue;
         }
        if(validatorRange.isValid(getNumber(), 1, 10) == false) {
            System.out.println(validatorRange.messageError());
            continue;
            }
        } while(validatorRange.isValid(getNumber(), 1, 10) == false);
    return getNumber();
}

public int[] fillingInputArray(int number) {
    ValidatorPrime validatorPrime = new ValidatorPrime();
    String inputStringPrime;
    int[] array = new int[getNumber()];
    int numberPrime = 0;

    for(int i = 0; i < array.length; i++) {
        do {
            System.out.println(validatorPrime.messageInput());
            try {
                inputStringPrime = scanner.nextLine();
                numberPrime = Integer.parseInt(inputStringPrime);
            }
            catch (NumberFormatException e) {
                System.out.println(validatorPrime.messageInformation());
                continue;
            }
            if(validatorPrime.isValid(numberPrime, 1, 100) == false) {
                System.out.println(validatorPrime.messageInformation());
                continue;
            }
            if(validatorPrime.isValid(numberPrime) == false) {
                System.out.println(validatorPrime.messageError());
            }
        } while(validatorPrime.isValid(numberPrime) == false);
        System.out.println((i + 1) + ". kor volt.");
        array[i] = numberPrime;
        }
    return array;
}

public void close() {
    scanner.close();
    }
}

 

Main.java

public class Main {
public static void main(String[] args) {
    UserInputHandler userinputhandler = new UserInputHandler();
    int number = userinputhandler.readInputNumberForArray();
    System.out.println(number);
    int[]array = userinputhandler.fillingInputArray(number);
    System.out.print("A tömb eleme(i): ");

    for(int i = 0; i < array.length; i++) {
        System.out.print(array[i] + " ");
    }
    userinputhandler.close();
    }
}

Végeredmény:

Kerem adja meg, hany szamot szeretne beadni (1 és 10 kozott)!
0
Kerem, hogy csakis a tartomanyon belul adjon meg szamokat! Probalja ujra!
Kerem adja meg, hany szamot szeretne beadni (1 és 10 kozott)!
11
Kerem, hogy csakis a tartomanyon belul adjon meg szamokat! Probalja ujra!
Kerem adja meg, hany szamot szeretne beadni (1 és 10 kozott)!
q
A muvelet vagy a szam nem ervenyes! Probalja ujra!
Kerem adja meg, hany szamot szeretne beadni (1 és 10 kozott)!
4
4
Kerem adja meg a szam(okat) (1 és 100 kozott)!
0
A muvelet vagy a szam nem ervenyes! Probalja ujra!
Kerem adja meg a szam(okat) (1 és 100 kozott)!
100
A szam nem primszam! Probalja ujra!
Kerem adja meg a szam(okat) (1 és 100 kozott)!
q
A muvelet vagy a szam nem ervenyes! Probalja ujra!
Kerem adja meg a szam(okat) (1 és 100 kozott)!
2
1. kor volt.
Kerem adja meg a szam(okat) (1 és 100 kozott)!
5
2. kor volt.
Kerem adja meg a szam(okat) (1 és 100 kozott)!
68
A szam nem primszam! Probalja ujra!
Kerem adja meg a szam(okat) (1 és 100 kozott)!
57
A szam nem primszam! Probalja ujra!
Kerem adja meg a szam(okat) (1 és 100 kozott)!
53
3. kor volt.
Kerem adja meg a szam(okat) (1 és 100 kozott)!
5
4. kor volt.
A tömb eleme(i): 2 5 53 5