Ez a dokumentum egy előző változata!
A programozók sokkal több kódot olvasnak mint írnak, ezért fontos, hogy kód ne legyen zavaros, mint a mocsár. A haladó programozók tudják, hogy a zavaros kódok, amiket vissza kell olvasni, nagyban lassítják a munkát. Mégis, sokszor úgy érzik, nekik is ilyet kell írniuk, csakhogy haladjon a munka. Az ilyen kód lehúz mint a mocsár, és nem fogjuk tudni tartani a határidőt.
A kódot ezért úgy kell megírni, hogy mindig olvasmányos legyen, kevés ránézéssel tudjuk mit csinál, meglepetések nélkül.
A kód tisztán írása és tartása, művészet.
Ez a rövid leírás Robert Martin: Tiszta kód című könyve alapján készül.
A változók, állandók, osztályok és függvények létrehozása során a rossz névadás a kódmocsár irányába lökjük a kódunkat.
A jó elnevezéshez három dolgot vizsgáljunk meg az elnevezendő részről:
Ha úgy érezzük megjegyzést kell fűzni egy változóhoz vagy állandóhoz, biztosan rossz az elnevezése.
int a; //A háromszög alapja
Kerüljük a félrevezető elnevezéseket. A közismert nevek például félrevezetők.
A bin, például Unix alapú rendszerekben a bináris szóra utal, illetve kettes számrendszerben megadott számokra is utalhat. Ha mi a belső indexet így szeretnénk rövidíteni, az félrevezető.
Példák az ismert azonosítókra, közismert és egyéni értelemmel:
A List szó félrevezető, ha olyan gyűjtemény nevében használjuk, ami nem List szerkezetben van tárolva. Például:
dolgozoList
Ilyenkor válasszuk például a következőket:
dolgozoCsoport dolgozok
Az O használata is megtévesztő lehet:
if( 0 == 35)
Válasszunk olyan neveket, amit könnyű kimondani. Ha egy névben nincsenek magánhangzók, nem könnyű azokat kimondani.
A dkn, a dolgozó keresztnevének rövidítésre például nem ajánlott:
dkn - dolgozó keresztnevek
Legyen helyette:
dolgozoKeresztnev
Az egybetűs azonosítók keresése rémálom. Kerüljük a használatát.
A névben a típus kódolása kerülendő. Régebben indokoltak voltak ezek az eljárások, mint a „magyar jelölés”, vagy az tagváltozó jelölése. A tagváltozót egy m_ karakter előtag párral jelölhetjük.
A felületek (interfész) nevébe sem ajánlott beletenni a i vagy I karaktereket. Helyette tegyük a hozzátartozó megvalósításba mondjuk Imp szót, vagy magyarul Megval, vagy hasonló szót.
DolgozoGyarMegvalositas DolgozoGyarMeg
Az osztálynevek legyenek mindig főnevek vagy főnévi kifejezések.
Robert Martin szerint kerülendők még a következő szavak az osztályok neveiben: Manager, Processor, Data, Info és hasonlók.
A tagfüggvények nevei mindig igék, vagy igei kifejezések.
Az elérő függvények előtagjai legyenek:
Ha magyar tagfüggvény neveket használunk, akkor nem valami szép az ilyen név:
getNev()
Ez hunglish nyelven van írva, azaz félig magyar, félig angol. Ha mégis mellette döntünk, akkor használjuk következetesen. Jobb ötlet megkeresni a szavak angol megfelelőjét:
getName()
Esetleg a get, set és is helyett magyar változatok keresése:
lekerNev() beallitNev()
Az is helyett nehéz a magyar nyelvben megfelelő szót találni.
A konstruktorok túlterhelése helyett, használjunk gyártó metódust.
Dolgozo dolgozo = Dolgozo.nevvel("Nagy János");
Kerüljük a jófejkedést, például szülőfüggvényecske.
Ha egy fogalomra használunk egy szót, akkor legyünk következetesek és mindig ezt használjuk.
fetchName() fetchCity() fetchSalary()
Vagy:
getName() getCity() getSalary()
A szóvicceket is kerüljük, de mit értünk szóvicc alatt? Két eltérő fogalmat ugyanazzal a szóval jelölünk.
Ha van megoldástartományból a szakmában használatos név, használjuk azt. Ha nincs maradhat a feladattartomány.
Vajon mit csinál a következő függvény?
trinangleCalc();
Többet mond, ha paraméterrel kell hívni?
triangleCalc(30, 35, 45);
Adott egy metódus, amely beállítja egy jármű sebességét, véletlenszerűen. Vagy gyorsít vagy lassít.
public Car extends JComponent { int d; Integer e; Car() { } public void doit(){ Random a = new Random(); boolean b = a.nextBoolean(); int c = a.nextInt(3) + 1; if(b) { if(d>(this.e + c)) { this.e = this.e + c; } }else { if((this.e - c) >0){ this.e = this.e - c; } } } }
A függvények mérete legyen minél kisebb. Ha 3-4 sor, akkor az már jó. Ennek eredménye lehet, hogy egy if vagy while törzsében csak egy függvényhívás van. Ez jó. Ha ilyen rövid függvényeink vannak, akkor valószínűleg elkerültük az egymásba ágyazott kifejezéseket is.
Egy függvény csak egyetlen feladatot csináljon, de azt jól csinálja.
A függvényeket fentről lefele írjuk egymás után. Ezt nevezik leszállószabálynak.
package haromszog; public class Haromszog { public static void main(String[] args) { double perimeter = calcPerimeter(30, 35, 40); System.out.println("Perimeter: " + perimeter); } public static double calcPerimeter(double sideA, double sideB, double sideC) { double perimeter = -1; if(isEditable(sideA, sideB, sideC)) { perimeter = sideA + sideB + sideC; } return perimeter; } public static boolean isEditable(double sideA, double sideB, double sideC) { boolean editable = true; if(sideA + sideB < sideC) { editable = false; } if(sideA + sideC < sideB) { editable = false; } if(sideB + sideC < sideA) { editable = false; } return editable; } }
class Sides { double a, b, c; public Sides(double a, double b, double c) { this.a = a; this.b = b; this.c = c; } }
public class Triangle { public static void main(String[] args) { Sides sides = new Sides(30, 35, 40); double perimeter = calcPerimeter(sides); System.out.println("Perimeter: " + perimeter); } public static double calcPerimeter(Sides sides) { double perimeter = -1; if(isEditable(sides)) { perimeter = sides.a + sides.b + sides.c; } return perimeter; } public static boolean isEditable(Sides sides) { boolean editable = true; if(sides.a + sides.b < sides.c) { editable = false; } if(sides.a + sides.c < sides.b) { editable = false; } if(sides.b + sides.c < sides.a) { editable = false; } return editable; } }
Keressük meg a legbeszédesebb neveket. Ha bizonytalanok vagyunk, próbáljunk meg több nevet is. Használjunk bátran hosszú neveket. A nevek megválasztásánál legyünk itt is következetesek.
Az a legideálisabb ha egy függvénynek egyetlen paramétere sincs.
Előfordul, hogy van egy paraméterünk, amivel kapcsolatban valamilyen kérdésre szeretnénk választ adni, vagy azon egy műveletet szeretnénk elvégezni. A függvény nevében következetesen szét kell választani ezt két tevékenységet.
Vannak a jelzőparaméterek, amelyek használatát kerülni kell. A jelző paraméter, amikor például átadok egy logikai paramétert, amely megmondja, hogy amin művelete kell végezni az milyen állapotban van. Az ilyen függvények helyett írjunk két függvényt, amely mindkét állapotra megoldást nyújt.
Tegyük fel, hogy van egy függvényünk, ami képes PostgreSQL és MariaDB adatbázishoz kapcsolódni. Hogy melyikhez kapcsolódik egy állandóval jelezzük.
class DatabaseConn { public Connection connect(DatabaseType.PostgreSQL) { ... } }
Az ilyen szerkezetek kerülendők. Írjunk helyette két külön függvényt. Az egyik PostgreSQL adatbázis kapcsolatához, a másik a MariaDB-hez.
Ha egy függvénynek 2-3 paraméternél többre van szüksége, csomagoljuk egy osztályba.
Ha egy művelet hatással van olyan változókra, objektumokra amely kívül esik tervezett célon, akkor azt mellékhatásnak nevezzük.
Adott egy függvény, ami MariaDB adatbázishoz kapcsolódik.
class Mariadb { boolean connected = false; public Connection connect() { ... connected = true; } }
Matematikai értelemben 1), ha egy függvénynek nincs visszatérési értéke, biztosan van valami mellékhatása. Például megváltoztatja az objektum állapotát.
Nekünk most, fontosabb mi a függvény létrehozásának célja. Ha megváltoztatja egy objektum állapotát, az lehet csak hatás, ha ez volt a függvény létrehozásának célja. Ha visszaad valamit a függvény, akkor általában nem az a célja, hogy megváltoztasson valahol egy objektumot.
class Program01 { public static void main(String[] args) { StringBuffer msg = null; getMessage(msg); System.out.println(msg); } public static void getMessage(StringBuffer msg) { msg.append("Helló Világ"); } }