Content extract
Komponens alapú programozás COM+ és .NET környezetben Marossy Kálmán (coloman@avalon.autbmehu) Dr. Charaf Hassan (hassan@avalonautbmehu) BME, Automatizálási és Alk. Informatikai Tanszék Bevezetõ Ez a cikk a komponens alapú szoftverfejlesztés alapvetõ nehézségeit tárgyalja, valamint azt, hogy az egyes problémák közül melyek, és hogyan küszöbölhetõk ki egy komponens infrastruktúra segítségével általánosan, valamint a COM+ és a .NET tekintetében A komponens alapú programozás A komponens alapú programozás egyre szélesebb körökben válik ismertté. Magának a komponensnek a definíciója nem teljesen azonos minden környezetben, ezért itt is célszerûnek tartottunk egy elég általános leírást: a komponens egy olyan bináris (lefordított) szoftver egység, amely által megvalósított funkció jól definiált formában, a komponens interfészén keresztül érhetõ el. Igény A komponens alapú programozás kialakulását és elterjedését
a következõ tényezõk tették szükségessé. Többek között az Internet elterjedésének köszönhetõen, és a PC-k jelentõs teljesítménynövekedésének és elterjedésének köszönhetõen is, a szoftver iránti igények jelentõsen megváltoztak. Ilyen követelmények például az igen rövid elkészülési határidõ, kitûnõ minõség, gazdaságosság, a változó igényekhez való gyors alkalmazkodás lehetõsége, skálázhatóság, könnyû integrálhatóság, modellekhez való könnyû illeszthetõség. [3] Ezeket a megnövekedett igényeket azonban egyre kevésbé sikerült kielégíteni a „hagyományos” szoftverfejlesztési eszköztárral új alapfilozófiára volt szükség, amit a komponens alapú programozás hivatott ellátni. Ez azonban változásokat tesz szükségessé mind a tervezés, mind a megvalósítás területein, és ezzel együtt a szoftverfejlesztõk gondolkodásmódján is. Alapgondolat A komponens alapú szoftverfejlesztés
alapgondolata nem új, tulajdonképpen az objektumorientált paradigmának mintegy továbbfejlesztett változata. Az alapötlet, hogy a már elkészített, és több helyen is szükséges szoftver egységeket ne kelljen újra és újra megírni, azok egy új, esetleg teljesen más applikációba beilleszthetõk legyenek. Különösen igaz az újrafelhasználhatóságra való igény, ha olyan bonyolult, komplex funkciókat valósít meg egy komponens, amiket kifejleszteni meglehetõsen idõigényes, és ennek megfelelõen költséges is. Ezek alapján a komponensek definiálása, elkészítése, tesztelése, továbbfejlesztése végül el is különül az egyes alkalmazásoktól, a komponens, mint funkcionális egység külön életet él. Típusok A „komponens alapú szoftverfejlesztés” többféle szoftverfejlesztési folyamatra utalhat, melyeket érdemes megkülönböztetni. Az egyik eset, amikor a saját magunk (cégünk, stb.) által kifejlesztett komponensekbõl
építkezünk. Ezzel élvezünk bizonyos elõnyöket, például a skálázhatóság, a változó modellekhez való könnyebb illeszthetõség, ugyanakkor egy bonyolult komponens esetében jelentõs ráfordítást jelenthet a komponens kifejlesztése. Egy teljesen más, és a korábbi tervezési tapasztalatainktól eltérõ szemléletmódot jelent, ha rendszerünket megvásárolható, mások által készített szoftver egységekbõl építjük fel. A tervezés szemléletében való eltérés szükségessége abból adódik, hogy a kereskedelemben beszerezhetõ komponensek nem pontosan a mi igényeinket elégítik ki, hanem egy „átlagos” igényt, ezen kívül ezek a komponensek könnyen változhatnak, de ezt a változást is a piacon megjelenõ újabb igények okozzák inkább, mint a mi konkrét igényünk. Ezekbe a komponensekbe nem látunk bele, létezhetnek nem dokumentált, vagy nem szabványos tulajdonságai is, és a komponensek integrálhatósága általában az adott
gyártó által készített egyéb komponensekkel könnyû, a többi esetben általában nem garantált. Azt sem szabad elfelejtenünk, hogy ezekhez az állandón változó, igen bonyolult komponensekhez naprakész tudás szükséges, aminek megszerzése szintén ráfordítást igényel, és a helyzet csak bonyolódik, ha figyelembe vesszük, hogy a különbözõ komponensek újabb és újabb verzióival valószínûleg frissíteni szeretnénk alkalmazásunkat. A szoftverfejlesztés ebben az esetben tehát további, jelentõs problémákat, megoldásra váró feladatokat vet fel. Komponens infrastruktúrák Láthatjuk, hogy a komponens alapú fejlesztés, bár ígéretesen hangzik, nem egyszerû feladat. Nézzük csak meg, hogyan állunk a szoftverfejlesztés különbözõ elemei, az analízis, a tervezés és az implementáció terén. Az analízis vizsgálatakor elmondhatjuk, hogy ahelyett, hogy az egyes, megvásárolható komponenseknek „jól definiált” lenne az
interfészük, egy csomó lefedetlen tulajdonság marad: nem illetve nem jól dokumentált tulajdonságok, a viselkedés nem kielégítõ leírása, minõségre vonatkozó dokumentáció (sebesség, memóriahasználat) hiánya. A tervezésnél gondot jelenthet, hogy az együttmûködõ komponenseink és komponens csoportjaink tulajdonságai jelentõsen változhatnak az újabb verziók során, valamint, hogy bizonyos, tényleges mûködéssel kapcsolatos tulajdonságok csak az implementáció alatt derülnek ki. Implementáció terén is találkozhatunk problémákkal: a különbözõ programnyelvek használata ma már általános, és az integrálás és a fejlesztés gyakran gondokat okoz ilyenkor. Ezeken a problémákon jelentõsen enyhíthet egy szabványos, robusztus, sok szolgáltatást magába foglaló komponens futtatókörnyezet, mely az elõre specifikált architektúrával segíti a tervezést, és ezen kívül igyekszik megoldani az interfészek jól specifikálását és a
több programnyelven való fejlesztés problémáját is. [2] Több komponens futtatókörnyezet létezik, például az EJB, COM+, CORBA, .NET Ezeknek az integrációja azonban még nem teljesen kiforrott, bár ezen a területen is jelentõs elõrehaladást láthatunk a korábbi évekhez képest. A COM+ A .NET és a COM+ a Microsoft által fejlesztett komponens futtató környezet A következõkben ezzel a két rendszerrel foglalkozunk. COM, DCOM, COM+ A Microsoft komponens rendszere fokozatosan fejlõdött ki. Az elsõ komponens rendszernek mondható környezetet a COM jelentette ebben a fejlõdési vonalban, mely az OLE továbbfejlesztésébõl nõtt ki. A COM definiálta a komponensek bináris formáját. A COM-mal kapcsolatos támogató függvények megvalósítása (például komponens betöltése) tulajdonképpen a Windows részének tekinthetõk. A COM-hoz tartozó kiegészítõ funkciók egy-egy elõre definiált (szabványosnak tekinthetõ) interfész saját, illetve
fejlesztõ eszközök által segített implementációjával vált lehetségessé. Ilyen kiegészítõ szolgáltatások a részletes hibainformáció biztosítása illetve kivételkezelés, perzisztenciakezelés, saját adatcsomagolási technika megvalósítása, kapcsolódási pontok létrehozása (kétirányú komponens kommunikáció). [5] A következõ lépcsõ a DCOM (Distributed COM) volt, mellyel már egy másik számítógépen lévõ komponenst is el lehetett érni. A COM+ a Windows 2000-ben jelent meg, és az eddigiekhez még különbözõ szolgáltatások biztosítását tette hozzá. A szolgáltatások egy része az MTS (Microsoft Transaction Server) COM+-ba való integrálásának köszönhetõ. COM+ szolgáltatások Ezek a fontosnak mondható szolgáltatások a következõk. [1] • Just-In-Time Activation Az erõforrás-kezelés optimalizálására egy komponens létrehozását késleltetjük az elsõ tényleges metódushívás idejéig, illetve megszüntethetjük,
amikor ideiglenesen nincs használatban a komponens. • Object Pooling Erre akkor lehet szükségünk, ha a komponens létrehozása több erõforrást igényel, mint a már létrehozott példány aktívan tartása. Ebben az esetben, szemben az elõzõvel, egy komponens akkor sem szûnik meg, ha már senki sem használja, hanem késõbbi újrahasznosításra a memóriában marad. • Load Balancing Egy skálázható rendszerben szükség lehet egy terhelés-kiegyenlítõ rendszerre, mely a több gépen egyenletes terhelést biztosítva próbálja meg a komponensek létrehozását. • Queued Components Az MSMQ-n (Microsoft Message Queue Server) alapuló megoldás segítségével egy kliens akkor is kezdeményezhet hívást egy komponenshez, amikor az éppen nem elérhetõ. Amint a komponens elérhetõvé válik, válaszol a hívásra • Szabály alapú hozzáférési jogosultságok A hozzáférés szabályozása fontos feladat egy komponens rendszer fejlesztésekor, ezért azt
egy komponens futtatókörnyezetnek mindenképpen érdemes támogatni. A COM+-ban erre szabály alapú hozzáférés-szabályozást (Role Based Security) találunk. • Események A korábbi kapcsolódási pontokon kívül egy eseményszolgáltatást is használhatnak a COM+ komponensek, melynek az az elõnye, hogy az eseményt igénylõ és az eseményt szolgáltató komponensek egymástól függetlenek, sõt, az egyes eseményekre való igény mindkét fél futásától függetlenül adminisztrálható • Tranzakciókezelés Kritikus mûveletek végzésekor szükség van tranzakciókezelésre, ami nagyobb komponens rendszereknél természetes igény. A COM+ a korábbi gyökerekbõl adódóan az OLE Transactions specifikációban szereplõ protokollt támogatja, melyet a MS DTC (Microsoft Distributed Transaction Coordinator) valósít meg. Ezen a protokollon kívül az X/Open DTP XA szabványt is támogatja. A COM+-ról elmondhatjuk, hogy egyrészt alapvetõ
alkalmazás-architektúrát definiál szoftver komponenseink számára, másrészt bizonyos gyakran használatos, jól definiált problémák megoldásához integrált szolgáltatásokat biztosít. És pontosan ez az, ami a komponens alapú fejlesztés tervezési fázisában nagy segítséget jelent számunkra szemben az általunk összerakott, könnyen változni tudó szoftver komponens csoportokkal. A COM+ hátrányai A korábban említett jeles tulajdonságok mellett azonban meg kell említeni néhány hátulütõjét is a COM+-nak. A COM-ban a komponensek interfésze egy programnyelvtõl független, interfészleíró nyelv, az IDL (Interface Definition Language) nyelv segítségével történtek. Ezek alapján egy komponens interfészének leírása elkülönült a komponenstõl, és a komponens az IDL-lel a kliens nyelvére mégis erõs megkötéseket tett (a Microsoft IDL fordítója viszonylag kevés nyelvet támogat, például a ma általánosnak számító modern szkript
nyelvekhez nem készült idl fordító). A Microsoft ezt felismerve bevezette a type library-k (tlb-k), vagy típuskönyvtárak fogalmát. A tlb amellett, hogy külön fájlként szerepelhet, bele is lehet illeszteni a lefordított komponensbe. De a komponenst az adott felhasználási helyen regisztrálni kell felhasználásuk elõtt, vagyis a típusinformációt be kell írni a registrybe – ami installációs és verzióproblémákhoz is vezet. Egy másik kívánatos igény komponens alapú programozásnál, mint azt már láttuk, hogy a komponens rendszer implementálása több programnyelven is mehessen. Bár történt erre törekvés, és a komponens bináris szabványa ezt elvileg lehetõvé is teszi, gyakorlatilag a helyzet nem ilyen egyszerû. A COM komponensek bináris szabványa leginkább a C++ nyelvhez közeli (az interfész gyakorlatilag egy virtuális függvénytábla), ami sok nyelvbõl nehézzé vagy nehézkessé teszi a használatát. Ez persze a komponensek
létrehozásakor is igaz Így a COM-ot használni tudó nyelvek köre viszonylag szûkös, a COM komponensek létrehozására képes nyelvekbõl még kevesebbet találunk. Bár a COM+ mint komponens infrastruktúra sok elõnnyel rendelkezik, van némi nehézkessége, és néhány hátránya, amikkel meg kell tudni küzdeni. A .NET A Microsoft felismerte, hogy ezeket a hátrányokat hogyan lehet jól kiküszöbölni, és a komponens alapú fejlesztést megkönnyítõ, jobban átgondolt alapokra helyezni, valamint a COM+ néhány eddigi hiányosságát pótolni. Ezért jött létre a NET platform A következõkben azt nézzük meg, hogy mik szükségesek a fenti problémák megoldásához, és hogy ezek mûködése végül milyen következményekkel jár a komponens alapú szoftverfejlesztést illetõen. Szerkezet Vizsgáljuk meg a .NET felépítését, és a hozzá tartozó új elemeket [6] • Common Language Runtime (CLR) A .NET egyik alappillére a Common Language Runtime, vagy
röviden CLR A CLR az általa futtatott és menedzselt kódnak különbözõ szolgáltatásokat nyújt, ilyen például az automatikus memóriakezelés. A CLR által végrehajtott kód nem egy adott processzor natív kódja, hanem egy köztes kód, a MSIL (Microsoft Intermediate Language). Az MSIL kód natív kóddá alakítása is a futtatórendszer feladata. Ezzel a CLR által támogatott kód elvileg hordozhatóvá válik. A NET-et támogató compilereknek erre a köztes nyelvre kell tehát fordítaniuk. • .NET Class Library (NET osztálykönyvtár) Egy másik, igen fontos alappillér a .NET osztálykönyvtár Különbözõ, az applikációk valamint a komponensek készítésekor gyakran használatos osztályokat tartalmaz, valamint elõre definiált interfészeket. Az osztályokat használhatjuk különbözõ rendszerszolgáltatások elérésére, vagy éppen örökölhetünk is belõle. Az interfészeket megvalósíthatjuk illetve örökölhetünk belõle. • Common Type
System (Egységes adattípusok) Az egységes, minden nyelvbõl használható típusok definiálása fontos szerepet játszik a több programnyelven való fejlesztés problémájának megoldásában. Bár ez azt jelenti, hogy az adott nyelvnek be kell tartania bizonyos szabályokat, csak ezzel volt elérhetõ például, hogy gyakorlatilag bármely (igen sok támogatott nyelvet találunk) programnyelvbõl tudjuk használni a másik nyelven készített osztályokat, sõt, akár örökölni is tudunk belõle. A NET osztálykönyvtárat is ezen ok miatt tudjuk hasonló módon használni. • Metaadat, és önleíró komponensek Mint korábban láthattuk, sok problémát vet fel, ha egy komponenshez tartozó adatokat a komponenstõl függetlenül (idl fájlban, vagy típuskönyvtárban a registryben) tároljuk. A komponensrõl szóló adatokat a NET-ben a komponenssel együtt tároljuk. Így egy helyen tárolódik a komponensrõl az összes fontos információ: a komponens azonosítása,
verziója, a típus neve, megvalósított interfészek, õsosztály, láthatóság, a komponens metódusai és tulajdonságai, és nem utolsó sorban egyes biztonsági beállítások. Ezeket az adatokat a komponenst felhasználó ki tudja nyerni, és a szükséges korlátozásokat (például jogosultságok) a CLR be tudja tartatni. • Assemblyk Az egyik hiányosság, amit a COM+-ban nem találtunk meg, az a komponensek egy egységbe, építõelembe való helyezése. Az installálás, verziókezelés, újrafelhasználás, biztonsági kérdések mind egy nagyobb egység, az assemblyk szintjén jelenik meg. • Application Domain Az egyes alkalmazások elkülönítése nem processz szinten történik, hanem „alkalmazás tartományonként”. Erre azért van szükség, mert a processz, és az alkalmazások elkülönítése (memóriahasználat, biztonsági kérdések, stb.) valamelyest eltérõ fogalmak, és egy processzben több elkülönített alkalmazás is
futhat. Míg a processzek közötti átjárás viszonylag lassú folyamatnak tekinthetõ, addig az egyes tartományok közötti átjárás gyorsabb. Ez jelentõs gyorsítást jelenthet, ha a tartományok intenzíven kommunikálnak. A .NET-hez ezeken kívül hozzátartozik, hogy átlátszóan tud együttmûködni a már meglévõ COM+ komponensekkel bármely irányban (és természetesen tudja használni a COM+ szolgáltatásokat). Tehát egy COM+ komponensbõl elérhetõ egy NET komponens, illetve egy .NET komponensbõl egy COM+ Ezt a kétirányú kompatibilitást mindenképpen szükséges volt fenntartani, hogy mint újonnan megjelenõ komponens rendszer kellõ számú felhasználóra találhasson könnyû legyen az „átállás”. Az eredmény Az új szemlélet bevezetése azzal járt, hogy a .NET elég nagymértékben teljesíti a komponens alapú rendszerek fejlesztésénél a jó komponens infrastruktúrára tett kívánalmainkat. Az analízis szempontjából nézve, a
komponens tágabb értelemben vett interfészének leírása (tehát nem csak a megvalósított interfész függvényei, hanem egyéb, a konkrét komponenssel kapcsolatos adatok) megtalálhatók a komponenssel együtt tárolt metaadatokkal. A tervezést segítõ szabványos komponens architektúra szintén megtalálható, és a COM+ által kínált szolgáltatások sora sem szûkült, hiszen azok elérhetõk a .NET-bõl is Az implementációs részt segíti egyrészt a több nyelv együttmûködését támogató Common Type System, és a keretrendszer többi része is, a nagyobb blokkokból való építkezést és a könnyû installálást az assemblyk megjelenése. Nem szabad elfelejtenünk azonban, hogy a .NET igazi sikeressége a komponens alapú szoftverfejlesztés terén – új technológia lévén – még bizonyításra vár. Együttmûködés más rendszerekkel A .NET-ben egy, az elõzõekben vizsgáltaktól eltérõ tényezõre is figyelmesek lehetünk Egy nagy méretû
elosztott, komponens alapú rendszer esetén valószínûleg szükségünk lehet a más rendszerekkel való összeillesztésre. Manapság általános nézetnek mondható, hogy ilyen helyzetekben közös adatreprezentációként XML nyelvet használjunk, és az interoperabilitás is könnyen történhet ezen a nyelven. Ezért a NET-ben különösen nagy hangsúlyt fektettek az XML támogatásra (akár az osztálykönyvtárat nézve, de még a runtime egyes funkcióit tekintve is), valamint könnyen elérhetõvé tudjuk tenni a .NET komponenseket egy szabványosnak mondható, rendszerek közötti komponenselérést végzõ, XML nyelvû protokollon, a SOAP-on keresztül. A támogatás nem csak a más komponens rendszerekkel való együttmûködést segíti, hanem az egyes komponensek Weben keresztüli elérésének, az úgynevezett Webes szolgáltatásoknak az alapja is. Összefoglalás Láthattuk tehát, hogy a komponens alapú fejlesztés milyen problémákat vet fel, és azokra hogyan
próbál egyre jobb választ találni a COM+, majd késõbb a .NET Azonban a szabványos komponens rendszerek által támogatott komponens alapú szoftverfejlesztés buktatóinak felfedezésére majd csak ezen rendszerek intenzív használata után kerül sor valószínûleg. Irodalom [1] Eddon, G.-Eddon, H: Inside COM+ Base Services, Microsoft Press, 1999 [2] Wallnau, K. C-Hissam, S A-Seacord, R C: Building Systems from Commercial Components, Addison-Wesley, 2002 [3] Allen, P.: Realizing e-Business with Components, Addison-Wesley, 2001 [4] Platt, D. S: Bemutatkozik a Microsoft NET, Szak Kiadó, 2001 [5] Marossy, K.: COM alapú többrétegû alkalmazások fejlesztése heterogén környezetben, BME AUT Diplomaterv, 2001 [6] Microsoft Visual Studio .NET Documentation (RC1)