1. Komponensalapú programozás
Meglehetősen elterjedt vélemény szerint az
objektumorientált programozás komoly
problémákkal bír a kód
újrafelhasznalhatósága terén még
akkor is, ha a domináns dekompozíció
egyeduralmából adódó
problémákat figyelmen kívül hagyjuk.
Közismert tény, hogy nagyobb programokat nehéz az
objektumorientált dekompozíció
módszerével elkészíteni. A főbb okokat a
következőkben szokás megjelölni.
- Az objektumok csatolása erős, egymástól
nehezen szeparálhatók, tehát a rendszert
nehéz szétszedni független egységekre
- A tervezés során gyakran keletkeznek olyan
egységek, amelyek egynél több objektumból
állnak, az objektum, mint egység, gyakran túl
kicsi az analízis számára
- A fordítás, letöltés és
telepítés során objektumok együttműködő
csoportját együttesen kell eljuttatni a
célgéphez és összekötni a már ott
levő szoftverelemekkel
Ezen problémák kezelésére hozták
létre a komponensalapú rendszereket, melyek a
következő részletekben különböznek az
objektumorientált rendszerektől.
- A komponensek egymástól teljesen
függetlenül léteznek, egymástól
függetlenül kell tudni azokat fejleszteni, telepíteni
és a rendszerrel összekötni.
- Egy komponens több (esetleg nagyon sok) objektumot
tartalmazhat
- A komponenseknek telepítési formátumuk van,
amely lehetővé teszi telepítésüket,
frissítésüket és
eltávolításukat egyenként vagy csoportokban.
A komponensorientált rendszerek jellemző megoldásai a
következők.
- A komponenseknek jól meghatározott bemenő és
kimenő interfészei vannak, melyek szabadon
csatlakoztathatók azonos típusú
interfészekhez. Az interfész kialakítása
olyan, hogy a külső komponensmenedzser összeköthet
és szétválaszthat komponenseket (nincs direkt
hivatkozás egyik komponensből a másikba).
- A független szét- és
összekapcsolhatóság miatt a komponensek
életciklusa (elindított/leállított)
vezérelhető. A komponensek egymástól való
függése megadja az elindítási sorrendet, ezen
felül ha a komponensrendszer dinamikus (a komponensek jönnek
létre és pusztulnak el futás közben, valamint
az összekötésük változik), akkor
átkonfigurálás közben a komponenseket le kell
állítani.
- A komponenseknek telepítési formátumuk van
és telepítési életciklusuk. Ez
lehetővé teszi, hogy inkrementálisan, egyenként
telepítsük őket, majd az interfészeiken
keresztül összekössük őket. Az inkrementális
telepítés szükségessé teszi, hogy a
komponensek teljesen "fekete dobozként" viselkedjenek
egymás számára, tehát az
öröklődés nem jöhet szóba komponensek
között.
A komponensorientált programozás nagyon elterjedt, szinte
minden nagyobb programot ebben implementálnak. A komponensek
belsejében gyakran objektumorientált
megközelítésben írják a programot.
Fejlett komponensrendszerek, pl. a Microsoft COM képesek
különböző nyelveken írt programokat is
összekötni.
Számos komponensrendszer létezik Jávára. A
Jáva osztályok jobban kielégítik a
komponensalapú rendszerek követelményeit, mint
mondjuk a C/C++ osztályai, még a legegyszerűbb
komponensrendszerhez is szükség van egy konvenció
definiálására a kimenő interfészek
csatolására. Ez a JavaBeans specifikáció.
Ezen felül az EJB egy specializált komponensrendszernek
tekinthető. Önálló, rendkívül
teljesítőképes Jáva-alapú komponensrendszer
a Fractal [2].
2. JAsCO
A JAsCO rendszer célja, hogy aspektus-szerű működést
valósítson meg JavaBeans komponensek között. A
JavaBeans egy egyszerű Jáva konvenció, amely megmondja,
milyen metódusokat kell tartalmaznia egy metódusnak, hogy
JavaBeans kompatibilis legyen. JavaBeans komponensek
eseményekkel kommunikálnak egymással. Az
eseményfogadó metódus ilyen
formátumú interfésszel rendelkezik:
Az eseményfogadó egy EventListener-bôl
leszármazott
interfészt implementál. Ebben az interfészben
fogja
össze az eseményfogadó metódusait.
Példa:
interface KeyKlickedListener extends java.util.EventListener {
void KeyKlicked( KeyKlickedEvent ke );
}
Ezeket az eseményfogadókat regisztrálják az
eseményküldőknél. Az eseményküldők ilyen
metódusokkal rendelkeznek:
set<interfész típus>(
<interfésztípus> )
Pl:
setKeyKlickedListener(
KeyKlickedListener lst );
Az eseményküldőknél lehetséges több
fogadó regisztrálása vagy fogadó
eltávolítása más
aláírású metódusokkal.
A JAsCO úgy bővíti ki a JavaBeans modelt, hogy két
újfajta elemet vezet be. Az aspektus-komponens megmondja, hogy
mikor és mi hajtódjon végre.
class
AccessManager {
PermissionDb p db = new PermissionDb();
User
currentuser = null;
void
login(User user, String pass) { //login code }
void
logout() { //logout code }
void
addAccessManagerListener(AML listener) { //adding code }
void
removeAccesManagerListener(AML listener) { //remove code }
hook AccessControl {
AccessControl(method(..args)) {
execute(method); }
replace() {
if(p_db.check(currentuser,cobject) {
return method(args); }
else {
throw new AccessException(); }
}
}
}
A hook rész azt mondja meg, hogy mikor hajtódhat
végre a szűrő. A tanács rész megmondja, hogy a
szűrő végrehajtásakor hogyan változik a
végrehajtás. A mi esetünkben az elkapott
metódus helyettesítődik egy olyannal, amelyik ellenőrzi
egy bizonyos engedély meglétét és
kivételt dob, ha az engedély nincs meg.
Az aspektus-komponenst egy
konnektor-komponenssel
kapcsoljuk a többi komponenshez.
connector
PrintAccessControl {
AccessManager.AccessControl control = new AccessManager.AccessControl(
* Printer.*(*));
control.replace();
}
Ez elfogja a Printer osztályban elhelyezkedő bean (a Printer
komponens) összes metódushívását.
A JAsCO el tudja fogni a bean által kibocsátott
eseményeket is.
Logging.FileLogger
logger = new Logging.FileLogger( onevent
Printer.jobFinished(PrintEvent));
Az eddigiek eléggé emlékeztettek az AspectJ
metódushívás-elfogó mechanizmusaira. A
JAsCO teljesen másképpen szövi az aspektusokat, mint
az eddig látott rendszerek, kihasználja a komponensek egy
fontos jellemzőjét, a komponensek dinamikus
összekapcsolhatóságot, hogy az
aspektus-komponenseket és konnektorokat beiktassa a
hívási láncba.
A JAsCO a bean összes hívását egy kapoccsal
szereli fel (ezt megteheti, mert az objektum csak az
interfészén keresztül érhető el) és ez
a kapocs a hívásokat a konnektortárba küldi,
ahol a hívást illesztik az aktuálisan aktív
konnektorokra és esetleg meghívják a hook-okat az
aspektuskomponensben. Ugyanez történik az
eseménykibocsátó metódusokban: ott
úgy manipulálják az
eseménygenerátorok és fogadók
közötti kapcsolatokat, hogy az esemény a
konnektortárba fusson be, ahol ugyancsak illesztik az onevent
konnektorokra.
A JAsCO csak az metódushívásokat ill. az
eseménykibocsátásokat tudja elfogni, hiszen a
komponensek belseje számára láthatatlan.
3. Fractal-AOP
A Fractal egy komponensrendszer, melynek különböző
nyelvi implementációi vannak. Legfőbb
jellegzetessége az, hogy hierarchikus, tehát
komponensekből újabb komponensek állíthatók
össze és ez az "összerakás" tetszés
szerinti mélységben folytatható. A Fractal
komponensek membránból és tartalomból
állnak. A membrán implementálja a komponens
menedzseléséhez szükséges
interfészeket, teszi elérhetővé a komponens
interfészeit ill. kapcsolja a tartalmat a membrán belső
felének interfészeihez. A tartalom maga a komponens
implementációja.
A Fractalhoz aspektusorientált kiterjesztést alkottak, ez
a Fractal-AOP. A Fractal-AOP célja
aspektusorientáltsághoz hasonló mechanizmus
megvalósítása a Fractal komponensmodell
membránjának és hierarchikus
komponenskompozíciójának
segítségével. Az alábbi kép egy
komponenst mutat, amelyhez aspektust illesztettünk.
A Fractal-AOP "becsomagolja" az aspektussal ellátandó
komponenst, egy külső membránt húz köré.
Ennek a külső membránnak két új
interfésze van, a cEc és az sPc. A cEc a külső
membrán elfogó (interceptor) mechanizmusához
kapcsolódik, elfogja a komponenshez érkező
kéréseket és továbbítja a szövő
komponens (weaving component) sEc interfészéhez
események formájában. A szövő komponens
kiértékeli a kapott eseményt, esetleg
meghívja a tanács komponenst (advice component), majd a
hívást továbbküldi az eredeti komponens sPc
interfészéhez. Az sPc interfész a megkapott
üzenetet újra hívássá alakítja
és az eredeti komponens megfelelő metódusa
meghívódik.
A Fractal-AOP arra is képes, hogy a komponensrendszer
különböző helyeire illeszkedő aspektusokat egy
egységbe fogja össze, így a rendszer akkor is
konzisztens állapotban marad, ha több komponens
szükséges egy aspektus
megvalósításához. Az alábbi
példán pl. az autentikációs aspektust
három komponens valósítja meg.
4. Összefoglalás
Aspektusokhoz hasonló funkcionalitás komponensekkel is
megvalósíthatók. Ezek csak a
komponensinterfészeken képesek működni,
lévén a komponens belseje fekete doboz. A komponensek
szabad összekapcsolhatósága azonban a
komponensinterfészekhez illesztett aspektusok
beillesztését a rendszerbe egyszerűvé teszik.
[1]
Cuno Pfister, Clemens Szyperski: Why Objects Are
Not Enough, Proceedings of the First
International
Component Users Conference,
Munich, Germany 1996 July
[2]
Fractal
[3] Davy Suvée, Wim Vanderperren and Viviane Jonckers: JAsCo: an
Aspect-Oriented approach tailored for Component Based Software
Development,
AOSD 2003, Boston
[4] Houssam Fakih, Noury Bouraqadi, Laurence Duchien: