Gyakorlati alapok

Gyorsan tanuljuk meg: a refaktorálás

 

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

A refaktorálás (angol szakszóval refactoring) egyszerűen fogalmazva a kód optimalizálását vagy valamilyen szintű manipulációját jelenti.

 

Például alacsony szintű a refaktorálás, ha a kódban egy metódust szeretnénk átnevezni (rename). Ez azonban nem csupán a MS Word szövegszerkesztő program Csere parancsa, hiszen a metódusra való hivatkozás sok osztály rengeteg helyén fordulhat elő és a fejlesztői környezetnek (a jelen esetben az általunk használt Eclipse platformnak) az összes hivatkozást érzékelnie és az átnevezés során javítania kell.

 

A magas szintű refaktorálás során a fejlesztői környezetnek bizonyos mértékig már a kód szemantikai, tartalmi elemeit is tudnia kell kielemeznie. Ennek természetesen vannak korlátai, hiszen azért mégsem veheti át a programozó analitikus feladatát, de bizonyos esetekben azt jelentős mértékben megkönnyítheti. Az intelligens fejlesztői környezetnek többek között képesnek kell lennie:

Az alábbi rövid példában az alacsony szintű refaktorálás Átnevezés (rename) parancsát gyakoroljuk ki. A példakódok írása során ugyanis a magam részéről gyakran futottam bele abba a hibába, hogy kezdetben rossz vagy valamilyen szempontból helytelen változó-, vagy metódusnevet adtam meg; szerintem ezzel mások is ugyanígy lesznek. Ha a nevet többször felhasználtam már, akkor érdemes volt inkább a refactor - rename műveletet kiadnom, mint kézzel keresgélni meg az összes, névre való hivatkozást.

 

Ezen művelet kigyakorlására vegyünk egy olyan példakódot, amelyben egy változónév sokszor fordul elő. A lehetséges kódok közül én a Keresések rendezett tömbben című fejezetben ismertetett egyik tömbrendezéses algoritmust vettem elő:

 

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

 

 

 

 

 

 

 

 

import java.util.*;

public class Main {
public static void main(String[] args) {
    int [] tomb = new int[10];
    int keresettSzam = 0;
    int keresettSzamIndex = 0;
    Random rnd = new Random();
    Scanner in = new Scanner(System.in);
    boolean talalat = false;

    System.out.println("Tömb rendezés előtt:");
    for(int i = 0; i < tomb.length; i++){
        tomb[i] = rnd.nextInt(100) + 1;
        System.out.print(tomb[i] + " ");
    }

    System.out.println();

    do{
        System.out.print("Kérem, hogy adjon meg egy számot (1 és 100 között):\n");
        String szamString = in.nextLine();
        keresettSzam = Integer.parseInt(szamString);
        }while (keresettSzam < 1 || keresettSzam > 100);

    for(int i = 0; i <= tomb.length - 1; i++){
        for(int j = i + 1; j <= tomb.length - 1; j++){
            if(tomb[i] > tomb[j]){
                int tarolo = tomb[i];
                tomb[i] = tomb[j];
                tomb[j] = tarolo;
            }
        }
    }

    System.out.println("A rendezett tömb:");
    for(int i = 0; i < tomb.length; i++) {
        System.out.print(tomb[i] + " ");
    }

    System.out.println();

    int kozep = tomb.length / 2;
    if((keresettSzam >= tomb[kozep])){
        for(int i = kozep; i < tomb.length; i++){
            if(tomb[i] == keresettSzam){
                talalat = true;
                keresettSzamIndex = i;
                break;
            }
        }
    }
    else if(keresettSzam < tomb[kozep]){
    for(int i = kozep; i >= 0; i--){
        if((tomb[i] == keresettSzam)){
            talalat = true;
            keresettSzamIndex = i;
            break;
        }
    }
}
if(talalat == true){
    System.out.println("\nA keresett benne van a tömbben,

            a(z) " + (keresettSzamIndex+1) + ". indexen.");
}
else
    System.out.println("\nA keresett szám nincs a tömbben.");
    }
}
 

Végeredmény (például):
Tömb rendezés előtt:
8 22 35 27 61 27 86 84 53 52
Kérem, hogy adjon meg egy számot (1 és 100 között):
53
A rendezett tömb:
8 22 27 27 35 52 53 61 84 86

A keresett benne van a tömbben, a(z) 7. indexen.

 

Legyen most a feladat a tomb változónév átnevezése alapTomb változónévre!

 

A kódot először egy az egyben másoljuk a Main osztályba, majd kattintsunk arra a hivatkozásra, amelyben az átnevezendő változónév először fordul elő, ez mindig a változó deklarációja:

 

int [] tomb = new int[10];

 

Jelöljük ki a változónevet dupla egérkattintással, ekkor az Eclipse platform láthatóan szürkével kijelölte a változónév összes többi hivatkozását is.

 

Kattintsunk egyet rá jobb egérgombbal és a legördülő menüből adjuk ki a Refactor - Rename parancsot.

 

Ekkor a változónév alatt megjelenik egy kis szövegnégyzet és benne a következő utasítás olvasható:

 

Enter new name, press Enter to refactor

 

Tegyünk az utasítás szerint: írjuk be az új változónevet, majd nyomjunk meg az Enter billentyűt. Ám a gépelés során az Eclipse már folyamatosan az összes helyen írja át az új névre a régit, az Enter csak a parancs véglegesítése. Természetesen a kódban szemantikailag-tartalmilag semmi nem változott, ezért azonnal futtatható:

 

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

 

 

 

 

 

 

 

 

import java.util.*;

public class Main {
public static void main(String[] args) {
    int [] alapTomb = new int[10];
    int keresettSzam = 0;
    int keresettSzamIndex = 0;
    Random rnd = new Random();
    Scanner in = new Scanner(System.in);
    boolean talalat = false;

    System.out.println("Tömb rendezés előtt:");
    for(int i = 0; i < alapTomb.length; i++){
        alapTomb[i] = rnd.nextInt(100) + 1;
        System.out.print(alapTomb[i] + " ");
    }

    System.out.println();

    do{
        System.out.print("Kérem, hogy adjon meg egy számot (1 és 100 között):\n");
        String szamString = in.nextLine();
        keresettSzam = Integer.parseInt(szamString);
        }while (keresettSzam < 1 || keresettSzam > 100);

    for(int i = 0; i <= alapTomb.length - 1; i++){
        for(int j = i + 1; j <= alapTomb.length - 1; j++){
            if(alapTomb[i] > alapTomb[j]){
                int tarolo = alapTomb[i];
                alapTomb[i] = alapTomb[j];
                alapTomb[j] = tarolo;
            }
        }
    }

    System.out.println("A rendezett tömb:");
    for(int i = 0; i < alapTomb.length; i++) {
        System.out.print(alapTomb[i] + " ");
    }

    System.out.println();

    int kozep = alapTomb.length / 2;
    if((keresettSzam >= alapTomb[kozep])){
        for(int i = kozep; i < alapTomb.length; i++){
            if(alapTomb[i] == keresettSzam){
                talalat = true;
                keresettSzamIndex = i;
                break;
            }
        }
    }
    else if(keresettSzam < alapTomb[kozep]){
    for(int i = kozep; i >= 0; i--){
        if((alapTomb[i] == keresettSzam)){
            talalat = true;
            keresettSzamIndex = i;
            break;
        }
    }
}
if(talalat == true){
    System.out.println("\nA keresett benne van a tömbben,

            a(z) " + (keresettSzamIndex+1) + ". indexen.");
}
else
    System.out.println("\nA keresett szám nincs a tömbben.");
    }
}
 

Végeredmény (például):
Tömb rendezés előtt:
8 22 35 27 61 27 86 84 53 52
Kérem, hogy adjon meg egy számot (1 és 100 között):
53
A rendezett tömb:
8 22 27 27 35 52 53 61 84 86

A keresett benne van a tömbben, a(z) 7. indexen.

 

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

Refaktorálásnál vegyük figyelembe, hogy a rendszer csakis azt a változót-műveletet-objektumot képes látni (és ezáltal refaktorálás alá vonni), amelyik előzetesen deklarálva volt.