Gyakorlati alapok II.
Celsius-Fahrenheit váltó "kivételes" validálással
A fejezet előzményei az előző, Celsius-Fahrenheit váltó című fejezetben tanulmányozhatók.
Ugyanakkor nem szokásom, de most meg kell kérnem a Tisztelt Olvasót, aki tanulmányai során meglehet, hogy a Honlaptérképben lineárisan fentről lefelé halad: a jelen fejezet alapos átnézése előtt mindenképpen lapozzon a Kivételesen beszéljünk a kivételkezelésről című fejezetcsomaghoz és alaposan tanulmányozza át a benne foglaltakat. Az alább ismertetett programozástechnikai trükk ugyanis az ott leírtakra alapul.
Az egyértelműen következetlen ugrálás oka, hogy az alapként felhasznált Celsius-Fahrenheit váltó függvényeket jóval hamarabb írtam meg a kivételkezeléses fejezetcsomagnál és csak később bővítettem ki a jelen, validáló rutinokat tartalmazó résszel.
Ebben a fejezetben tehát a megalkotott kód validáló részét bővítjük ki egy külön függvény formájában, amely tehát valamilyen szempont szerint hiteles vagy érvényes (valid) kimeneti adatot fog szolgáltatni a belső hőmérsékletváltó függvényeknek.
Másképpen fogalmazva: a kódot "bolondbiztossá" kell tennünk, hogy ne kerüljön a rendszerbe rossz bemeneti adat, ami veszélyt jelenthet a rendszer futására vagy biztonságára nézve (véletlen vagy szándékosan rossz felhasználói adatmegadás, illetve szándékos hacker-támadások). Ugyanakkor belátjuk, hogy mindez még nem elégséges a rendszerek teljeskörű védelméhez.
A validálás elméletileg 2 szintű:
-
ellenőriznünk kell a felhasználó által megadott, csakis kizárólag String típusú bemeneti adatot; ennek sokféle szempontja lehetséges, így kijelenthetjük, hogy ez mindenképpen az általánosabb megközelítés,
-
szintén ellenőriznünk kell, hogy a konvertáló, azaz típusváltó függvények megfelelő formátumban kapják meg az adatokat; ez egyértelműen típusspecifikus, így konkrétabb, csakis a konvertáló függvények szempontjából lényeges.
-
Természetesen elismerjük, hogy a fenti 2 validálás összetartozhat, sőt működhet 1 függvényen belül is (néha azonban nem).
A már említett programozástechnikai trükk a következő:
a Kivételesen beszéljünk a kivételkezelésről című fejezetcsomagban lényegében arról olvashatunk, hogy a JVM rendelkezik egy belső, hibadetektáló szoftverkörnyezettel. Nem minden hibára tudunk előzetesen felkészülni, de igenis sok hiba előrelátható (talán legtipikusabb ilyen a 0-val való osztás; ezen előre jól meghatározható hibákat, futási problémákat egységesen kivételeknek nevezzük /exceptions/), így lehetőségünk van a hibát azelőtt "elkapni" (catch), mielőtt komolyabb gondokat okozna.
Nos, az alapelveket megértve az alábbi kód során csakis a 2. lépés szerint validálunk. Azaz rábízzuk magunkat a Java-rendszerprogramozóinak tapasztalatára, miszerint jól implementálták a konvertáló függvény (itt: fok = Double.parseDouble(bemenetiAdat)) validáló rutinjait. Ha a bemeneti adat a konvertálás (programozói műszóval parszolás) szerint rossz, akkor a rendszer hibát fog dobni (throw), amit lehetőségünk van elkapni (catch), sőt ezt ki is használhatjuk: addig nem is engedjük át a bemeneti adatot, amíg kivétellel szembesülünk.
A validálás ezen szintje első körben viszonylag biztonságos adatbevitelt eredményez, de nyilvánvalóan nem elég további, ennél specifikusabb követelmények ellenőrzésére. Például itt, a Celsius-Fahrenheit váltó esetében érdemes alsó és felső határokat is megállapítanunk, amelytől azonban most a jelen megoldásban eltekintünk.
Nézzük meg a futtatható Java-kódot!
import java.util.*;
public class Main {
static double szamBekeres(String valasztas){
boolean isValid = true;
double fok = 0;
Scanner in = new Scanner(System.in);
String bemenetiAdat = new String();
System.out.println ("\nKérem, hogy adja meg a fokot!");
do {
isValid = true;
bemenetiAdat = in.nextLine();
try{
fok = Double.parseDouble(bemenetiAdat);
}
catch(Exception e){
System.out.println("Rossz adatbevitel, kérem újra megadni!");
isValid = false;
}
} while(!isValid);
return fok;
}
static double celsiusFahrenheit(double fok){
return (fok * 1.8) + 32;
}
static double fahrenheitCelsius(double fok){
return (fok - 32) * 0.5555;
}
static void kiiras(double fok, double eredmeny, String valasztas){
if(valasztas.equals("1")){
System.out.println("\n" + fok + " C = " + eredmeny + " F");
}
else if(valasztas.equals("2")){
System.out.println("\n" + fok + " F = " + eredmeny + " C");
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
double fok = 0;
double eredmeny = 0;
String[] menu = new String[] {"1 - Celsius -> Fahrenheit", "2 - Fahrenheit ->
Celsius", "0 - Kilépés"};
while(true) {
System.out.println("\nKérem válasszon az alábbi lehetőségekből: ");
for(int i = 0; i < menu.length; i++) {
System.out.println(menu[i]);
}
String valasztas = in.nextLine();
if("1".equals(valasztas)) {
fok = szamBekeres(valasztas);
eredmeny = celsiusFahrenheit(fok);
kiiras(fok, eredmeny, valasztas);
}
if("2".equals(valasztas)) {
fok = szamBekeres(valasztas);
eredmeny = fahrenheitCelsius(fok);
kiiras(fok, eredmeny, valasztas);
}
if("0".equals(valasztas)) {
System.out.println("\nViszlát!");
in.close();
System.exit(0);
}
}
}
}
Végeredmény:
Kérem válasszon az alábbi lehetőségekből:
1 - Celsius -> Fahrenheit
2 - Fahrenheit -> Celsius
0 - Kilépés
1
Kérem, hogy adja meg a fokot!
12d
12.0 C = 53.6 F
Kérem válasszon az alábbi lehetőségekből:
1 - Celsius -> Fahrenheit
2 - Fahrenheit -> Celsius
0 - Kilépés
1
Kérem, hogy adja meg a fokot!
1n2
Rossz adatbevitel, kérem újra megadni!
00.1
0.1 C = 32.18 F
Kérem válasszon az alábbi lehetőségekből:
1 - Celsius -> Fahrenheit
2 - Fahrenheit -> Celsius
0 - Kilépés
1
Kérem, hogy adja meg a fokot!
3-q
Rossz adatbevitel, kérem újra megadni!
-3.e
Rossz adatbevitel, kérem újra megadni!
-46
-46.0 C = -50.8 F
Kérem válasszon az alábbi lehetőségekből:
1 - Celsius -> Fahrenheit
2 - Fahrenheit -> Celsius
0 - Kilépés
0
Viszlát!
Ellenőrzési segédlet:
-
0 C = 32 F
-
100 C = 212 F
-
0 F = -17,8 C
-
100 F = 37,8 C