Gyakorlati alapok III.
A Controller osztály lehetősége
Ha osztályszinten az objektumorientált elveket következetesen alkalmazzuk, akkor már egy viszonylag egyszerű alkalmazás megírásakor is szó szerint “osztályhegyek” fognak keletkezni. Vegyünk például egy lottósorsolásos algoritmust, teljes validálási igénnyel (a Virtuális ötös lottó című fejezetben leírtak alapján). Ekkor a következő funkcionális osztályok jöhetnek létre:
-
DataRequest – adatbekérési osztály
-
DataVerification – adatellenőrzési osztály
-
Hits – találatellenőrző osztály
-
Lottery – lottószámgeneráló osztály
-
Main – a main() főprogramot lefuttató osztály, ebben csak 1 osztályhivatkozás, esetleg mást nem is tartalmaz
-
Messages – az összes üzenetet tartalmazó osztály
-
Sorting – elemrendezési osztály
-
Tips – tippszámgeneráló osztály
Itt és most nem foglalkozunk azzal, hogy funkcionálisan optimális-e az osztályszétbontás. Igen, meg lehet oldani kevesebb osztállyal; nyilvánvalóan más, az alapelveket szintén jól megközelítő megoldások hatványozottan lehetségesek.
Ha a keletkezett osztályokat alaposan, de további szempontok nélkül gyúrjuk
össze, akkor az objektumorientált elveknek 1 nagyon következetesen megfelelő
és jól működő kódot fogunk kapni, azonban garantáltan lesz 1 gyenge pontja:
benne az osztályhivatkozások nehezen követhetők, rosszabb esetben pedig
rémbonyolultak. Ennek oka, hogy az osztályhivatkozások keresztül-kasul
hálózhatják be a kódot:
Meg kell jegyeznünk, hogy a jelenleg használatban lévő keretrendszerek
(például Eclipse) egyszerű billentyűparancsokkal támogatják ezen
hivatkozások ugrásszerű követését, ám ettől nem válik lényegesen könnyebbé a
kód értelmezése, főként szemantikai hibakereséskor.
A megoldás erre, hogy kialakítunk egy Controller osztályt, amelyben
célzottan “összeragasztjuk” az osztályokat, így a legtöbb osztályfuttatás
(nagyjából) 1 helyen lesz követhető:
Természetesen még ezután is lehetséges, hogy 1-1 osztály fog tartalmazni
egyéb osztályhivatkozást (lásd a fenti kép jobb felső sarkát); ez nem
probléma, mert a futtatás immár központilag vezéreltté, irányítottá válik és
ez óriási előny.
Emlékezzünk vissza: az osztályok önmagukban zárt, működő egységek. Egy osztály
elérése többféle opcióval is szabályozható (A
hozzáférés-módosítók
című fejezet), azonban egyvalami bizonyos:
belső adatai szigorúan privát elérésűek (private), azaz “belső magánügy”.
Ez alapvető problémát szokott okozni főként azon tanítványoknál, akik éppen ezen témakörrel ismerkednek, hiszen gyakran megteszik, hogy kívülről közvetlen elérést adnak a változók tartalmához, ahelyett, hogy getter-setter függvényeket használnának fel. Ha azonban okosan alkalmazzák az adatelrejtést, akkor az is gyakran megesik, hogy az osztályok összeillesztésekor rejtélyes szemantikai hibák jelentkeznek. Ennek rengeteg oka lehet, ám az egyik idevágó: az osztályok már annyira zártak, hogy (nyilvánvalóan) nem tudnak egymás belső működéséről, ezért nem látják egymás belső változóit sem. Tehát egy osztályban futó ciklus, benne egy meghívott külső osztályhivatkozással egyáltalán nem biztos, hogy a kívánt mennyiségben fog lefutni. A Controller osztály alkalmazása erre is megoldást jelenthet, mert a működtető változók (nagyobbrészt) 1 osztályban futnak.