Az AspectJ programozási nyelv

Bevezetés



Az AspectJ nyelv eredete

Már több kísérlet is volt, ami megpróbálta az aspektus-orientált szemléletet implementálni, de ezek minduntalan elvi, vagy implementációs problémákban elakadtak. Az AspectJ nyelvet Gregor Kiczales, az AOP (Aspektus orientált programozás) megalkotója hozta létre, aki a Xerox PARC csapatának vezetője. A nyelvvel szemben támasztott követelmények, hogy lehessen használni a már megírt Java kódokat, hogy ne legyen nehéz a programozónak az új paradigma megtanulása, és hogy átláthatóbb kódot generáljunk. Ez a csapat dolgozta ki a nyelvet, és fejlesztette ki a fordítóprogramokat, és a fejlesztői eszközöket. A projekt 1997-ben indult, 1998-ban tették először elérhetővé külső felhasználók számára, az első kiadás pedig 2001-ben volt. Az aspektus orientáltság alapfogalma a "cross-cutting" (keresztülvágó) problémák kezelése, illetve annak lehetővé tétele, hogy ezek a máskülönben a program sok részében szétszóródó, és ismétlődő kódrészletek is modularizálhatók legyenek, ezáltal egységesebb kódot kapjunk. Erre egy megvalósítás, az AspectJ nyelv, amely teljes egészében a Java aspektus-orientált kiterjesztése, ezért minden alapvető vezérlési elem megegyezik vele.

Bevezető

Ebben a részben az AspectJ azon szolgáltatásainak rövid bemutatására kerül sor, melyeket a fejezet további részeiben használni fogunk. Ezek a nyelv lényegi szolgáltatásai, azonban nem nyújtanak teljes képet az AspectJ-ről.

A modularitás központi fogalom a programok bonyolultságának kezelésében. Ezt segítik a különböző módszertani elvek (dekompozíció, hierarchia, komponensen belül összetartó erő, komponensek között vékony interfész, enkapszuláció, információ elrejtés, osztályok, csomagok, könyvtárak), melyek megvalósítását az ezeket támogató programozási nyelvekkel vihetjük végbe.

A szemantikát egy egyszerű alakzatszerkesztő rendszerrel szemléltetjük. Egy Figure néhány FigureElementből áll, ami vagy Point vagy Line. Az Figure osztályban vannak gyártó metódusok. Ezen kívül van még egy Display. A legtöbb példa program ebben a fejezetben szintén ezen a rendszeren alapszik. UML a FigureEditor példához:

UML a FigureEditor példához












A domináns dekompozíció szerint osztottuk szét az osztályok között a feladatokat, azaz a fő feladat szerint. Ha nem használunk más dekompozíciót, azaz nem veszünk figyelembe más vonatkozásokat (concerns), például a megjelenítést (display), akkor a megjelenítés programkódja számos helyen megjelenik az osztályainkban: elszóródik (scattering) és összekuszálódik (tangling). Így a megjelenítés nem lesz moduláris, keresztülvág a fő vonatkozásunkon (crosscutting concern). Ilyen keresztülvágó vonatkozásra számos példa van egy szoftver rendszerben: loggolás, authentikáció, authorizáció, security, kivételkezelés, szinkronizáció, adatok helyességének ellenőrzés, megjelenítés, debug, tranzakció-kezelés.

Motiváció

OOP programokban így megfigyelhető a következő két (nem túl kellemes) jelenség:

Az AspectJ-t (és hasonlóan más aspektus-orientált nyelveket) ez a motiváció hozta létre, és az a felismerés, hogy bizonyos esetek nem kezelhetők megfelelően a hagyományos programozási módszerekkel. Vegyük azt a problémát, amikor egy alkalmazásban bevezetünk biztonsági jogosultságokat. Természeténél fogva a biztonsággal foglalkozó program rész a program modularitásának számos természetes alapegységében megjelenik. Illetve a továbbiakban a jogosultságokat egységesen kell kezelni, a program további bővítésekor. Ezen felül maga a jogosultság kezelése fejlődhet idővel. Éppen ezért az ilyen és ehhez hasonló esetek kezelése nehézkes, és óriási hibaforrás a hagyományos program nyelvekben. Ezeket a programrészeket hívjuk keresztbevágó vonatkozásoknak, vagy angolul „cross-cutting concerns” – nek.

Példa: loggolás a tomcat webszerverben












Példa: loggolás a tomcat webszerverben. A piros rész a loggolással foglalkozó sorokat jelöli, látható, hogy teljesen szét van szóródva az osztályokban a kód.

A modernebb nyelvekben a modularizáció alapját egyre inkább a típusokra bontás jelenti, azaz egy modul egy típust implementál. Az ilyen esetek, mint a jogosultságok kezelése nem kezelhető egy természetes programozási alapegységen belül. Az objektum orientált programozási nyelveknél a modularitás természetes alapegysége az osztály. A keresztbevágó vonatkozásokat nehéz (sokszor nem is nagyon lehet) egy osztályba zárni, nehéz modularizálni.

Az ilyen vonatkozások kezelése, mint a jogosultságoké "átvág"-ja a modularitás természetes egységeit. Az objektum orientált nyelveknél a természetes egység az osztály. De az ilyen vonatkozásokat nem lehet osztályokba zárni, mert "keresztülvág"-ják az osztályokat, emiatt nem hasznosíthatók újra, nem lehet továbbfejleszteni őket, leszármaztatni belőlük, szétszóródnak a program legkülönbözőbb részeiben, röviden: nehéz velük dolgozni.

Az aspektus orientált programozás az ilyen keresztvonatkozások kezelésének egyik módja, ahol a modularitás a közös vonatkozások alapján történhet. Az AspectJ egy Java alapú megvalósítása az aspektus orientált programozásnak.

AspectJ egyetlen új fogalmat ad a Java nyelvhez a join point (csatlakozási pont) fogalmát, és néhány új konstrukciót: pointcut, advice, inter-type declaration és aspect. A pointcut és advice dinamikusan befolyásolja a program végrehajtást, míg az inter-type declaration statikusan befolyásolja a program osztály hierarchiáját.

Egy join point egy jól definiált pont a program végrehajtásában. A pointcut-ok kiválasztanak néhány ilyen pontot, és néhány értéket ezekben a pontokban. Egy advice definiál egy kódrészt, mely végrehajtódik, ha egy bizonyos pointcut-ot elér a végrehajtás. Ezek alkotják AspectJ dinamikus részeit.

Az AspectJ lehetőséget ad statikus módosításokra is. Egy inter-type declaration módosíthatja az osztályok tagjait, illetve az osztályok közötti kapcsolatokat.

Az utolsó új konstrukció az aspect. Egy aspect az egysége a nyelv modularitásának. Egy aspect pointcut-okból, advice-okból, és inter-type declaration-ökből áll.