axióma alapú automatizált teszteléssel



Hasonló dokumentumok
Szoftverprototípus készítése. Szoftverprototípus készítése. Szoftverprototípus készítése

IFJÚSÁG-NEVELÉS. Nevelés, gondolkodás, matematika

Mobil készülékek programozása

Rendszertervezés 2. IR elemzés Dr. Szepesné Stiftinger, Mária

Nemzeti Alaptanterv Informatika műveltségterület Munkaanyag március

Előzmények

7. Verifikáci. ció. Ennek része a hagyományos értelemben vett szoftvertesztelés is. A szoftver verifikálásának,

Bánsághi Anna 1 of 67

Honlapkoncepció. Miskolc város hivatalos honlapjához

3.1. Alapelvek. Miskolci Egyetem, Gyártástudományi Intézet, Prof. Dr. Dudás Illés

SZÉCHENYI ISTVÁN EGYETEM

AJÁNLÁSA. a központi közigazgatási szervek szoftverfejlesztéseihez kapcsolódó minőségbiztosításra és minőségirányításra vonatkozóan

A Szekszárdi I. Béla Gimnázium Helyi Tanterve

DSI működésre. tervezve. Hogyan fog kinézni a jövő informatikai infrastruktúrája? Egész szoftverrendszerek egy

Elektronikus közhiteles nyilvántartások Megvalósítási tanulmány

Információ-architektúra

TERMÉKTERVEZÉS PANDUR BÉLA TERMÉKTERVEZÉS

Vállalati integrált kockázatkezelés (II. rész)

Bánsághi Anna Bánsághi Anna 1 of 54

INFORMATIKA. 6 évfolyamos osztály

A SZOFTVERTECHNOLÓGIA ALAPJAI

Egyes kockázatelemzési (veszélyazonosítási) módszerek alkalmazásának értékelési, illetőleg ellenőrzési szempontjai

A római számok tanításának módszertani problémái

A térinformatika lehetőségei a veszélyes anyagok okozta súlyos ipari balesetek megelőzésében

Zárójelentés. Az autonóm mobil eszközök felhasználási területei, irányítási módszerek

MINŐSÉGIRÁNYÍTÁS (PQM) ÉS MONITORING ISMERETEK

Szakmai zárójelentés

Tartalom. CCNA Discovery 4 9. fejezet Ajánlatkészítés

Számviteli tanácsadás. IFRS felmérés Fókuszban a pénzügyi beszámolók

ÓBUDAI EGYETEM Neumann János Informatikai Kar Informatikai Rendszerek Intézet Témavezető: Bringye Zsolt

Ismeretanyag Záróvizsgára való felkészüléshez

9904 Jelentés a társadalombiztosítás informatikai rendszereinek ellenőrzéséről

Csak felvételi vizsga: csak záróvizsga: közös vizsga: Mérnökinformatikus szak BME Villamosmérnöki és Informatikai Kar május 27.

Informatika. Magyar-angol két tanítási nyelvű osztály tanterve. 9. évfolyam

Komponens modellek. 3. Előadás (első fele)

Informatikus informatikus Térinformatikus Informatikus T 1/9

Az alábbi áttekintés Délkelet-Európa (a volt Jugoszlávia országai

VÁLLALATI INFORMÁCIÓS RENDSZEREK, INTERNETES TECHNIKÁK

SZAKDOLGOZAT. Kiss Albert

2.1.A SZOFTVERFEJLESZTÉS STRUKTÚRÁJA

Rendszerterv. 1. Funkcionális terv Feladat leírása:

A második, azaz az utolsó előtti félév az esslingeni masteren

SZENT ISTVÁN EGYETEM GÖDÖLLŐ. DOKTORI (PhD) ÉRTEKEZÉS - TÉZISFÜZET

CÉLZOTT TERMÉKEK ÉS SZOLGÁLTATÁSOK PI- ACI VIZSGÁLATA

Hogyan kerül(jön) az e-könyv a könyvtárba?*

Nyugat-magyarországi Egyetem Geoinformatikai Kara. Dr. Székely Csaba. Agrár-gazdaságtan 8. AGAT8 modul. Vállalati tervezés és fejlesztés

6. AZ EREDMÉNYEK ÉRTELMEZÉSE

Cégismerteto. Ez így kicsit tömören hangzik, nézzük meg részletesebben, mivel is foglalkozunk!

AZ OMBUDSMAN ALAPJOG-ÉRTELMEZÉSE ÉS NORMAKONTROLLJA *

PHP5 Új generáció (2. rész)

Követelmények a megbízható működés terén. Információbiztonsági osztályozás a megbízható működés szempontjából. T - T üz T

Informatika szigorlati témakörök gazdasági informatika egyetemi képzés hallgatói részére

Állami Számvevőszék ELEMZÉS a évi integritás felmérés óvodák, bölcsődék intézménycsoportban mért eredményeiről május

Bevezetés, platformok. Léczfalvy Ádám

1 Rendszer alapok. 1.1 Alapfogalmak

A. ZDRAVOMISZLOV: A SZOCIOLÓGIAI KUTATÁSOK MÓDSZERTANA

Adat és információvédelemi kérdések a kórházi gyakorlatban II.

A MEGBÍZHATÓSÁGI ELEMZŐ MÓDSZEREK

Objektum Orientált Szoftverfejlesztés (jegyzet)

TÁVOKTATÁSI TANANYAGOK FEJLESZTÉSÉNEK MÓDSZERTANI KÉRDÉSEI

Közbeszerzési Értesítő száma: 2015/108

(11) Lajstromszám: E (13) T2 EURÓPAI SZABADALOM SZÖVEGÉNEK FORDÍTÁSA

P-GRADE fejlesztőkörnyezet és Jini alapú GRID integrálása PVM programok végrehajtásához. Rendszerterv. Sipos Gergely

Adatbázisok I Adatmodellek komponensei. Adatbázis modellek típusai. Adatbázisrendszer-specifikus tervezés

Általános statisztika II. Kriszt, Éva Varga, Edit Kenyeres, Erika Korpás, Attiláné Csernyák, László

KERTVÁROSI ÁLTALÁNOS ISKOLA OM: PEDAGÓGIAI PROGRAMJA

A NATO katonai képességfejlesztése a nemzetközi béketámogatási tevékenység érdekében

1. Funkcionális terv Feladat leírása: 1.2. Rendszer célja, motivációja:

A bemeneti mérés eredménye az 1. évfolyamon

ellenõrzés rendszere és módszerei Szerkesztette Kovács Árpád

Füstmentesítő berendezések állandó üzemképességének fenntartása

ALAPKÖVEK A JÓ STRATÉGIÁHOZ

Vállalkozás alapítás és vállalkozóvá válás kutatás zárójelentés

SZEMLÉLETES RÉSZINFORMÁCIÓK INTEGRÁCIÓS PROBLÉMÁINAK VIZSGÁLATA A VIRTUÁLIS VALÓSÁGOT TEREMTŐ SZIMULÁTOROK ALAPJÁN

Bocz János Jéghegyek. Tévhitek, avagy a magyar nonprofit szektor mélyrétegei

felsorolt A vezetők és a beosztott pedagógusok teljesítményértékelési rendszerének

ÁLTALÁNOS JELLEGŰ ELŐÍRÁSOK. A hitelesítési folyamat résztvevőit, az alapelemeket és a főbb kapcsolódási pontokat az 1.

Az emberi tényező vizsgálata az információbiztonság, a személyés vagyonvédelem, valamint az épületkiürítés területein

NOD32 Antivirus 3.0. Felhasználói útmutató. Beépített összetevők: ESET NOD32 Antivirus ESET NOD32 Antispyware. we protect your digital worlds

Doktori munka. Solymosi József: NUKLEÁRIS KÖRNYEZETELLENŐRZŐ MÉRŐRENDSZEREK. Alkotás leírása

Book Template Title. Author Last Name, Author First Name

IBM Business Monitor 7. változat 5. alváltozat. IBM Business Monitor telepítési kézikönyv

SZENT ISTVÁN EGYETEM

INTEGRÁLT ÖNKORMÁNYZATI RENDSZER

MINŐSÉGELLENŐRZÉSI ÖSSZEFOGLALÓ

FELÜLVIZSGÁLATI JEGYZŐKÖNYV (E-DS10F1_TANF-SW) MELLÉKLETE

tanúsítja, hogy a Kopint-Datorg Részvénytársaság által kifejlesztett és forgalmazott MultiSigno Standard aláíró alkalmazás komponens 1.

Mit kell és mit célszerű szabályozni a vállalkozáson belül?

.NET Microsoft.Net Framework

Fiáth Attila Nagy Balázs Tóth Péter Dóczi Szilvia Dinya Mariann

Széchenyi István Szakképző Iskola

MŰANYAGOK FELDOLGOZÁSA

Előterjesztés a Képviselő-testület december 16. napján tartott ülésén 6. napirendi pont

3 Hogyan határozzuk meg az innováció szükségszerűségét egy üzleti probléma esetén

TERMÉK FEJLESZTÉS PANDUR BÉLA TERMÉK TERVEZÉSE

Mérés és értékelés a tanodában egy lehetséges megközelítés

Antreter Ferenc. Termelési-logisztikai rendszerek tervezése és teljesítményének mérése

1. Az informatikai eszközök használata

Működési kockázati önértékelések veszteségeloszlás-alapú modellezése

Tarantella Secure Global Desktop Enterprise Edition

Átírás:

.NET programok minőségi mutatóinak javítása axióma alapú automatizált teszteléssel Doktori értekezés Szerző: Biczó Mihály Témavezető: Dr. Porkoláb Zoltán Eötvös Loránd Tudományegyetem Informatika Doktori Iskola Iskolavezető: Dr. Benczúr András Az informatika alapjai és módszertana doktori program Programvezető: Dr. Demetrovics János 2012

A projekt az Európai Unió támogatásával, az Európai Szociális Alap társfinanszírozásával valósul meg (a támogatás száma TÁMOP 4.2.1./B-09/1/KMR-2010-0003).

Köszönetnyilvánítás Szeretném megköszönni témavezetőmnek, dr. Porkoláb Zoltánnak a dolgozat elkészítése során nyújtott értékes észrevételeit, lelkiismeretes, alapos lektorálását, a sok konzultációs időpontot, amit biztosított számomra. Áldozatos munkája nélkül a dolgozat sokkal több hibát tartalmazna. Köszönöm szüleim egyetemi és posztgraduális tanulmányaim során nyújtott támogatását, a folyamatos ösztönzést és biztatást, amelyek új témák keresésére és vizsgálatára sarkalltak. Kitartó szeretetük nélkül nem készülhetett volna el ez az értekezés. Köszönet illeti feleségemet, Ginát, amiért megteremtette számomra a dolgozat megírásához szükséges biztos hátteret, a nyugodt munkakörülményeket, bár sokszor nélkülöznie kellett a társaságomat munkám és a kutatási feladatok összeegyeztetése érdekében. Köszönöm az Eötvös Loránd Tudományegyetem Programozási Nyelvek és Fordítóprogramok Tanszék tanszékvezető egyetemi tanárának, dr. Horváth Zoltánnak a lehetőséget, hogy fiatalos, inspiráló környezetben, számos konferencián előadóként szerepelve és gyümölcsöző külföldi kapcsolatokat építve dolgozhattam. A tanszék munkatársai és doktorandusz hallgatói értékes szakmai javaslatokkal segítették munkámat. Külön köszönöm dr. Kozsik Tamásnak, Mihalicza Józsefnek, Pataki Norbertnek, dr. Pócza Krisztiánnak (szerzőtársamnak), és dr. Zólyomi Istvánnak a jobbító szándékú megjegyzéseket.

Tartalomjegyzék Bevezetés 1 1. A dolgozat eszközrendszerének rövid áttekintése 5 1.1. Szoftverminőségi mutatók.............................. 5 1.1.1. Külső szoftverminőségi mutatók....................... 6 1.1.2. Belső szoftverminőségi mutatók....................... 10 1.2. Programok helyessége................................ 11 1.2.1. Objektumorientált programok helyessége................. 11 1.2.2. Az Eiffel helyességi specifikációs nyelve................... 13 1.3. Az aspektusorientált programozásról........................ 14 1.4. A.NET keretrendszer áttekintő ismertetése.................... 15 1.5. Függőségek injektálása................................ 18 1.6. Összefoglalás..................................... 21 2. A programhelyesség-ellenőrzés alapjai.net környezetben 23 2.1. A fejezet célkitűzése................................. 23 2.2. Kapcsolódó kutatások és áttekintés......................... 23 2.2.1. Modell alapú helyességi specifikáció.................... 23 2.2.2. Aspektusorientált lehetőségek a.net platformon............. 25 2.3. Elméleti háttér.................................... 34 2.4. Magas szintű áttekintés............................... 36 2.5. A megvalósítás részletei............................... 37 2.5.1. A helyességi specifikációs nyelv és az elemző elkészítése......... 37 2.5.2. Szerződések megadása............................ 39 2.5.3. A köztes reprezentáció előállítása...................... 40 2.5.4. A végrehajtás megszakítása - függőségek injektálása........... 41 2.5.5. Ellenőrző metódus generálása, az ellenőrzés elvégzése........... 44 2.5.6. Teljesítményelemzés............................. 45 2.6. A tézis megfogalmazása............................... 47 i

TARTALOMJEGYZÉK 3. Axiomatikus specifikáción alapuló teszteset generálás 49 3.1. A fejezet célkitűzése................................. 49 3.2. Kapcsolódó kutatások és áttekintés......................... 50 3.3. Elméleti háttér.................................... 52 3.3.1. A koncepció definíciója............................ 52 3.3.2. Axióma.................................... 53 3.3.3. Modell..................................... 54 3.3.4. Axióma alapú tesztelés............................ 55 3.4. Magas szintű áttekintés............................... 55 3.4.1. A modell, mint sablon interfész implementáció.............. 55 3.4.2. Axiómák leírása tagfüggvényként...................... 59 3.4.3. Axiómák ábrázolása attribútumok segítségével.............. 60 3.4.4. Axiómák és öröklődés............................ 61 3.5. A megvalósítás részletei............................... 62 3.5.1. Axióma alapú tesztelés magas szintű áttekintése............. 62 3.5.2. Absztrakt monoid koncepció........................ 62 3.5.3. A híváselfogás kezelése............................ 64 3.5.4. Axióma attribútumok felderítése...................... 65 3.5.5. Tesztesetek generálása az axiómák alapján................. 66 3.5.6. A generálás folyamata és az axiómák ellenőrzése............. 66 3.6. A tézis megfogalmazása............................... 68 4. Nyomkövetésen alapuló releváns tesztadat generálás 71 4.1. A fejezet célkitűzése................................. 71 4.2. Kapcsolódó kutatások és áttekintés......................... 72 4.2.1. Lehetséges elvárások............................. 72 4.2.2. Kapcsolódó munkák............................. 75 4.2.3. A fejezetben vizsgált kérdések........................ 76 4.3. Elméleti háttér.................................... 76 4.3.1. Általános naplózás.............................. 76 4.4. Magas szintű áttekintés............................... 78 4.5. A megvalósítás részletei............................... 78 4.5.1. Szekvenciapontonkénti, futásidejű naplózás................ 80 4.5.2. A naplózó művelet.............................. 81 4.5.3. Belső reprezentáció.............................. 82 4.5.4. A köztes kód átírása............................. 83 4.5.5. Naplózás a változók szintjén......................... 87 ii

TARTALOMJEGYZÉK 4.6. Teljesítményelemzés................................. 92 4.7. A napló fájl és a generátor eljárás összekapcsolása................ 93 4.7.1. Módosított axióma reprezentáció...................... 94 4.8. A tézis megfogalmazása............................... 96 5. Hibajavítás a gyakorlatban - esettanulmány 97 5.1. A fejezet célkitűzése................................. 97 5.2. Az alkalmazás kiválasztásának szempontjai.................... 98 5.3. Az alkalmazás bemutatása.............................. 99 5.4. Hiba az alkalmazásban................................ 100 5.5. Hiba megelőzése helyességi specifikációval..................... 101 5.6. Hiba megelőzése axiomatikus teszteléssel...................... 102 6. Összefoglalás 107 6.1. Összegzés....................................... 107 6.2. Kitekintés, további vizsgálatok........................... 109 Angol nyelvű összefoglaló 111 Ábrák jegyzéke 113 Kódrészletek jegyzéke 114 Algoritmusok jegyzéke 116 Táblázatok jegyzéke 117 Tárgymutató 118 Irodalomjegyzék 119 iii

Bevezetés A hardver eszközök teljesítményének gyors növekedése [78] lehetővé tette egyre bonyolultabb problémák számítógéppel támogatott megoldását. A készülő rendszerek mind méretben, mind bonyolultságban próbára tették az emberi elme befogadóképességét, előállításukhoz csoportmunkára és technológiára volt szükség. A szoftvertechnológia [100] fő kihívása előírt minőségű szoftver termék adott költségkerettel és erőforráshalmazzal határidőre történő előállítása. Tíz éves ipari környezetben felgyülemlett, különféle szerepkörökben összegyűjtött tapasztalatom alapján tudom, mennyire nehéz feladatról van szó. Már szakmai pályafutásom elején ráéreztem arra, hogy nem lehet költséghatékonyan és határidőre megvalósítani egy projektet, ha a szoftver minőségére vonatkozó kritériumok a kivitelezés során háttérbe szorulnak. Ezen felismerésem nyomán kutatási érdeklődésem a,,jó minőségű alkalmazások létrehozása felé fordult, miközben a szoftverminőség mibenlétéről még nem volt szilárd képem. A szoftverminőség összetett fogalom, amely számos emberi és technológiai tényezőtől függ: a fejlesztői csapat tagjainak pszichológiai adottságaitól kezdve a hatékony projektmenedzselési technikákon keresztül egészen az alkotók szakmai felkészültségéig és a felhasznált programozási környezetig - csupa olyan dolog, amely mind pozitív, mind negatív irányban befolyásolhatja az elkészült termék minőségét. Nem szabad megfeledkezni arról a tényről sem, hogy a különféle projektek eltérő technológiai, emberi és menedzsment elvárásokat támaszthatnak a kivitelező csapattal szemben. Általános üzleti igényeket kielégítő rendszerek fejlesztése során - amilyen egy webáruház, foglalási rendszer, útvonaltervező vagy a világhálón elérhető prezentációs eszköz - érdemes olyan módszertant választani, amely nem ró túlzott adminisztrációs kényszert a fejlesztőkre, a betartandó szabályok száma csekély. Mindamellett a módszertannak képesnek kell lennie a dinamikus üzleti környezetből fakadó változások kezelésére. Az ilyen jellegű módszertanokat agilis módszertanoknak [63] is szokták nevezni. Az agilis módszertanok már a 90-es évek közepétől (dokumentált formában pedig a 2000-es évek elejétől [8]) teret hódítottak. Sikerüket elsősorban annak köszönhetik, hogy nagyméretű projektek során igazolták, képesek megfelelni a szoftvertechnológia fő elvárásainak a napjainkban jellemző gyorsan változó üzleti környezetekben. 1

BEVEZETÉS Nyilvánvaló, hogy más alkalmazási területeken - orvosi diagnosztikai/képalkotó berendezések, sejtszintű manipulátorok (génsebészet), vegyi vagy nukleáris üzemek, közlekedés - akár emberi életek is múlhatnak szoftver termékek helyes működésén. Ilyen környezetben igazoltan helyes, nagy megbízhatóságú [100] termékekre van szükség, amelyek előállítása eltérő menedzsment és kivitelezési technikákat kíván meg. Hasonlóképpen, magának a technológiának a kiválasztását is jelentősen befolyásolja az alkalmazási terület: amíg Adában [84], C-ben és C++-ban [54, 102] implementálható egy új metróvonal szemaforjait irányító modul; addig sem a Java, sem a.net platform végfelhasználói szerződése nem teszi lehetővé olyan szoftver készítését, amelyen emberi életek múlhatnak. A feladatnak megfelelő fejlesztői csapat kiválasztása a cégeknek dolgozó toborzókat állítja nehéz helyzet elé [95]. Talán nem véletlen, hogy nagyon sikeresek a munkaerőkölcsönzéssel foglalkozó cégek, illetve, hogy a fejlett országokban működő nagyvállalatok egyre inkább szerződött partnereknek adják át a fejlesztési feladatokat [81]. A siker - akár üzleti, akár nagy megbízhatóságú rendszerek esetén - számos tényező megfelelő együttállásán múlik. Dolgozatomban arra vállalkozom, hogy bemutassam: kizárólag technológiai megfontolások mentén is elérhető a minőség javítása. A közölt eljárások többsége általánosítható más programozási környezetre is 1. A bemutatott eredményeket a.net platformon valósítottam meg, ennek megfelelően a példákat a C# programozási nyelven adom meg. Dolgozatom felépítése az alábbi: az 1. fejezetben áttekintem a dolgozat általános elméleti hátterét. Definiálom a szoftverminőség fogalmát, megadom a fontosabb szoftverminőségi mutatókat. Kijelölöm közülük azokat, amelyekkel részletesen kívánok foglalkozni. Ezután röviden ismertetem az Eiffel programozási nyelv helyességi specifikációs nyelvét. (Az Eiffel napjaink népszerű programozási környezete, amely közvetlen nyelvi eszközöket ad a minőségi mutatók javítására.) A fejezet második felében a.net alkalmazásfejlesztői platform - a későbbi fejezetek szempontjából lényeges - szolgáltatásait és a C# nyelvi elemeit tekintem át. Látni fogjuk, hogy téziseim felhasználják az aspektusorientált programozás alapelemeit, így a fejezet végén röviden ismertetem az aspektusorientált programozási paradigmát. A 2. fejezetben megadom dolgozatom első tézisét. Megvalósítom az Eiffel nyelv szerződés alapú programozási szolgáltatásait.net/c# környezetben. Ehhez aspektusorientált programozási technikákat használok fel, kiemelem a függőségek injektálásán alapuló módszert. Megtervezek egy egyszerű helyességi specifikációs nyelvet és annak fordítóprogramját. A fordító által előállított köztes reprezentációból futási időben generálom az ellenőrzéseket végrehajtó kódot, a hatékonyság növelése érdekében gyorsítótárat alkalmazok. Az implementáció a helyességi specifikációs nyelv szabad megválasztása miatt rugalmasabb, mint az Eiffel megoldása. 1 Elsősorban azok a programozási környezetek jöhetnek szóba, amelyek rendelkeznek futásidejű önellenőrző (introspection) képességekkel. 2

A 3. fejezet tartalmazza a dolgozat második tézisét, amelyben a korábban tárgyalt helyességi specifikációs eszköztár újszerű alkalmazási területét mutatom be. Eszközt adok arra, hogy elvont fogalmakhoz a helyesség szükséges feltételeiként interpretálható axiómákat kapcsolhassunk, és az axiómák alapján a fejlesztő számára transzparens módon, automatizáltan teszteseteket generáljunk és futtassunk. Módszerem nem csak új szoftver termékek létrehozása esetén használható; releváns bemeneti adatok mellett már meglévő rendszerek módosítását is megkönnyíti. A 4. fejezet a dolgozat harmadik tézise, amely a tesztadat generálás problémájával foglalkozik. Kidolgozok egy napló formátumot, amely objektumorientált programozási nyelvek szekvenciapontonkénti naplózására használható. A formátumot felhasználva elkészítem a naplógenerálás implementációját. Elvégzem a naplózó eljárás teljesítményelemzését, ami alapján megállapítom, hogy az ismertetett módszer a gyakorlatban is felhasználható. A 5. fejezetben egy esettanulmányt teszek közzé, amellyel a dolgozatban kidolgozott kétféle infrastruktúra (helyességi specifikációs, axiomatikus tesztelés releváns tesztadatokkal) gyakorlati működését kívánom szemléltetni. A 6. fejezetben rendszerezem és összegzem az elért eredményeimet. Egyúttal kitekintést nyújtok az ígéretes kutatási területekre. Az alábbi táblázat a felhasznált releváns publikációimat tartalmazza tézisenkénti bontásban. [13] [14] [15] [17] [90] [91] [92] I. II. III. 3

,,Napjainkban a legtöbb szoftver olyan, mint egy egyiptomi piramis: sok millió kő rabszolgamunkával egymásra halmozva, bárminemű szerkezeti integritás nélkül. (Alan Kay) 1. A dolgozat eszközrendszerének rövid áttekintése Dolgozatomban azt a célt tűztem ki magam elé, hogy olyan eszközöket adjak a fejlesztők kezébe, amelyek segítségével lehetővé válik ipari alkalmazások minőségének a javítása. Mind a szoftvertechnológia definíciójában, mind célkitűzésemben szerepel a szoftverminőség fogalma. Annak érdekében, hogy beszélhessünk a minőség javításáról, definiálnunk kell a szoftver minőségi mutatóit. Ebben a bevezető szakaszban erre vállalkozom. 1.1. Szoftverminőségi mutatók A minőség összetett fogalom és számos nézetrendszer szerint vizsgálható. Kézenfekvő lehetőség a fejlesztők és a felhasználók szempontjából kategorizálni a szempontokat, hiszen ők azok, akik a fejlesztés vagy a felhasználás valamely fázisában interakcióba kerülnek a rendszerrel. Fejlesztői szempontból fontos minőségi kritérium a kód olvashatósága, a modularitás; objektumelvű rendszereknél a laza összekapcsolás (loose coupling), az erős kohézió (strong cohesion), az egy felelősség elve (single responsibility principle), a tervezési minták (design pattern) [39] tudatos használata, automatizált tesztesetekkel való lefedettség, kivételkezelés típusos kivételekkel, stb. A program szövegének, forráskódjának ismerete - kiegészítve esetleg a futásidejű jellemzők (teljesítmény) vizsgálatával - elégséges a minőség átfogó értékeléséhez. A végfelhasználó azonban más jellegű igényeket támaszt a rendszerrel szemben. Számára mindegy, hogy a rendszer architektúrája [96] mennyire elegáns, vagy a naplózáshoz használt adatbázis normalizált-e. Ugyanakkor fontosnak tartja a felhasználói felület ergonómikus kivitelét, az esztétikus megjelenést, az alacsony átlagos válaszidőt, a beszédes hibaüzenetek meglétét, a testre szabhatóságot, stb. A szoftverminőség fogalmának definiálásakor Bertrand Meyer ezt a természetes felosztást követi [74], és a minőséget befolyásoló tényezőket két nagy csoportra osztja. A belső szoft- 5

A DOLGOZAT ESZKÖZRENDSZERÉNEK RÖVID ÁTTEKINTÉSE verminőségi mutatók a fejlesztői szempontból, a külső szoftverminőségi mutatók pedig a felhasználói szempontból fontos tényezőket jelentik. A továbbiakban a külső minőségi mutatókat tekintem át röviden. 1.1.1. Külső szoftverminőségi mutatók Helyesség Definíció (Helyesség). A helyesség a szoftver azon jellemzője, hogy pontosan a tőle elvárt, a specifikációban megfogalmazott feladatokat hajtja végre. A helyesség a legfontosabb minőségi mutató, azonban vegyük észre, hogy a definícióban szerepel a specifikáció fogalma. Nagyméretű szoftverrendszerek specifikációja formális eszközökkel a gyakorlatban nehezen kivitelezhető feladat, hiszen már egy kisebb program esetében is annyi feltétellel, alrendszerrel találkozhatunk, hogy a helyesség megfogalmazása az összes tényezőt figyelembe véve nehézségekbe ütközik. Meyer azt javasolja, hogy használjuk ki napjaink szoftver rendszereinek azt a sajátosságát, hogy elkülönített, egymással lazán csatolt [64] rétegekből állnak. Így a helyesség vizsgálatát leszűkíthetjük egy-egy réteg izolált vizsgálatára, feltételezve, hogy az adott réteg alatt elhelyezkedő további rétegek mindegyike helyes. (A dolgozat későbbi részében látni fogjuk, hogy az Eiffel programozási nyelv megalkotásánál is hasonló mentális absztrakciót alkalmazott a tervező: a teljes program helyessége kisebb egységek, az osztályok helyességén keresztül definiált - ls. 1.1. algoritmus.) Robusztusság Definíció (Robusztusság). A robusztusság a szoftver azon jellemzője, hogy képes megfelelően reagálni nem megengedett bemenetekre. A helyesség definíciójánál láttuk azt az elvárást, hogy a rendszer megfelelően ellássa a specifikációban foglalt feladatát. Mindig lesznek azonban olyan esetek, amelyekre a specifikáció semmit sem követel meg. A robusztusság azt biztosítja, hogy ezek az esetek nem okoznak végzetes hibát, hanem az elvárható módon hibaüzenetet generálnak, vagy esetleg tisztán terminálják a program végrehajtását. A robusztusság tehát kiegészíti a helyesség fogalmát: minden, a specifikációban nem megfogalmazott esetben a programnak az elvárható legnagyobb gondossággal kell eljárnia. Kiterjeszthetőség Definíció (Kiterjeszthetőség). A szoftver kiterjeszthetősége annak mértéke, hogy a specifikáció változása esetén mennyire könnyű a programot módosítani. 6

1.1. SZOFTVERMINŐSÉGI MUTATÓK A szoftver módosítása elméletileg egyszerű feladat: a program szövegének birtokában pusztán át kell írni a megfelelő részeket. A nagy szoftverrendszereket azonban Meyer kártyavárhoz hasonlítja: egyetlen kártya áthelyezése vagy megmozdítása az egész kártyavár összeomlását okozhatja 1. A kiterjeszthetőség növelésének két igen fontos eszköze: Egyszerű architektúra: egy egyszerű architektúra mindig könnyebben kiterjeszthető, mint egy bonyolult. Decentralizáció: Minél nagyobb autonómiával rendelkeznek, minél lazábban csatoltak a rendszert felépítő modulok, annál kisebb valószínűséggel fog egy látszólag lokális módosítás láncreakciót elindítani, amely a rendszer egészének módosítását igényli. Gondoljunk az objektumorientált programozási paradigmára, amely sikerét nem kis részben annak köszönheti, hogy támogatja könnyen kiterjeszthető alkalmazások készítését. Az objektumorientált rendszer egy dinamikus gráf, amelynek csúcsai az objektumok, élei pedig az objektumok közötti kapcsolatok [98]. Az architektúra tipikusan kliens-szerver jellegű, az osztályok laza csatolása, az interfész alapú programozás pedig a decentralizáció megvalósításának eszközei. Újrafelhasználhatóság Definíció (Újrafelhasználhatóság). Az újrafelhasználhatóság a szoftverkomponens azon tulajdonsága, hogy több különböző alkalmazás építőköveként szolgálhat. A kód újrafelhasználhatóságának az igénye abban a felismerésben gyökerezik, hogy sok különböző alkalmazás azonos mintákat követ, így a fejlesztőknek hasonló problémákat kéne újra és újra megoldaniuk. Amennyiben lehetőséget teremtünk a kód hatékony újrafelhasználására, egységnyi idő alatt többet foglalkozhatunk a tényleges problémával, a megoldás minőségi, illetve kvantitatív mutatóinak a javításával. Ismét az objektumorientált paradigmát hozom fel példaként. Az objektumorientált programozási nyelvek többsége támogatja az objektumosztályok közötti öröklődést, amely a kód újrafelhasználásának erős eszköze [85]. Ugyanakkor az öröklődés túlzott alkalmazása a kiterjeszthetőség ellenében hat, hiszen a származtatott osztály örökli az ős minden adattagját és metódusát. Ez - lévén fehérdoboz típusú újrafelhasználás - erős függőséget teremt az ős és gyermek osztályok között, tehát az ős módosítása potenciálisan kihat minden belőle származó gyermekre, ez pedig módosítási láncreakciót indíthat el. 1 Nem megfelelően strukturált, monolitikus rendszerek esetében fokozottan igaz a megállapítás. 7

A DOLGOZAT ESZKÖZRENDSZERÉNEK RÖVID ÁTTEKINTÉSE A kódújrafelhasználás szép példája a tervezési minta (design pattern) [39]. A tervezési minták olyan megoldások, amelyek gyakran előforduló problémákra adnak általános érvényű válaszokat [99]. Alkalmazásuk elősegíti az újrafelhasználhatóság és a kiterjeszthetőség elérését. Kompatibilitás Definíció (Kompatibilitás). A kompatibilitás azt méri, milyen mértékben képesek a rendszer komponensei egymással együttműködni. A kompatibilitás eléréséhez fontos a terv homogenitása, illetve a modulok, vagy önálló programok közötti kommunikációs stratégiák egységessége, esetleg szabványosítása. Ilyen szabványos köztes (middleware) protokollok például a CORBA és a Microsoft COM technológiák. Hatékonyság Definíció (Hatékonyság). A hatékonyság a szoftver azon jellemzője, hogy menynyire bánik gazdaságosan a hardver erőforrásokkal (processzoridő, memória, sávszélesség). A hatékonyság gyakran a kód olvashatósága, illetve az absztrakció ellenében hat, ezért gyakori hozzáállás, hogy előbb működjön a kód megfelelően, csak azután foglalkozzunk a hatékonysággal. Olyan szaktekintélyek is osztják ezt a nézetet, mint Donald Knuth, aki szerint,,... az idő előtti optimalizásás minden rossz gyökere 2. Másfelől a fejlesztők hajlamosak túlzott erőfeszítést tenni apró optimalizálások érdekében. Erre akkor lehet szükség, ha a hatékonyság a specifikáció része. A specifikáció előírhatja a garantált válaszidőt a rendszer bizonyos szolgáltatásaival kapcsolatban - ilyenkor a hatékonyság a helyesség előfeltétele is egyben 3. Hordozhatóság Definíció (Hordozhatóság). A hordozhatóság azt méri, mennyire könnyű a szoftvert átvinni különböző hardver és szoftver környezetekbe. A Java platform a 90-es évek közepén megvalósított egy hardver-szoftver gépet, a Java Virtuális Gépet (Java Virtual Machine), amely jelenleg minden népszerű környezetben elérhető. 2 Ezt a hozzáállást tovább erősítette a hardver eszközök teljesítményének gyors növekedése is [78]. 3 A.NET platform végfelhasználói szerződése kategorikusan tiltja olyan alkalmazások készítését, amelyeken emberi életek múlhatnak. Meglepő azonban, hogy ez éppen a hatékonysággal van összefüggésben. A platform a szemétgyűjtés miatt ugyanis nem képes adott válaszidőt garantálni, ilyen módon egy kritikus helyzetben adott válasz esetleg már túl kései. 8

1.1. SZOFTVERMINŐSÉGI MUTATÓK A.NET a 2000-es évek elején hasonló, némileg kiforrottab koncepcióval megismételte a Java sikerét, azonban a futtató környezet kizárólag Windows operációs rendszerre készült el 4. Napjainkban a mobil eszközök elterjedésével a hordozhatóság problémája aktuálisabb, mint valaha. Majdnem minden nagy gyártó előállt a saját felhő alapú megoldásával (Microsoft, Google, Amazon), divatos fogalmak a szoftver, mint szolgáltatás (software as a service), az alkalmazás virtualizáció 5. A fent felsorolt technológiák mindegyikének az a célja, hogy a hordozhatóság problémáját megoldja, levegye ennek a terhét a fejlesztők válláról. A mottó: mindent csak egyszer kell elkészíteni, és annak minden környezetben működnie kell. Használhatóság Definíció (Használhatóság). A használhatóság - a könnyű telepítésen, intuitív működtetésen kívül - azt is jelenti, hogy különböző előképzettségű emberek egyformán képesek a szoftvert használni, és segítségével problémákat tudnak megoldani. A használhatóság egyik előfeltétele a strukturális egyszerűség. Egy jól átgondolt, gondosan megtervezett rendszert egyszerűbb megtanulni, megérteni, mint egy kevésbé rendezettet. Természetesen a tervezés és a felhasználás közötti koncepcionális szakadék miatt ez önmagában nem garantálja a sikert, de mindenképpen előnyösen befolyásolja a jó használhatóságot. Funkcionalitás Definíció (Funkcionalitás). A rendszer által felkínált különböző felhasználói lehetőségek száma. Gyakran nehéz kérdés annak eldöntése, hogy mely szolgáltatások elégségesek a felhasználók komfortérzetének biztosításához. Visszatérő helyzet egy-egy új verzió kiadásakor, hogy a felhasználók elégedetlenek bizonyos szolgáltatásokkal kapcsolatban. Ami az egyik felhasználónak egy régóta hiányolt funkció, az a másik számára akár zavaró is lehet. Általánosságban elmondható, hogy újabb szolgáltatások hozzáadása során a rendszer konzisztenciájának fenntartása a legfontosabb. A funkciók túlzott hajszolása jellemzően a szoftver termék minőségének általános romlásához vezet. 4 A Mono a.net nyílt forráskódú, platformfüggetlen, nem szabványos implementációja. Ipari jelentősége csekély. 5 A trendet jól mutatja, hogy a Microsoft új operációs rendszerének, a Windows 8-nak a tervezésekor eddig soha nem látott hangsúlyt kapott a hordozhatóság. A szoftveróriás ígérete szerint a Windows 8 képes lesz arra, hogy a nagy webkiszolgálóktól kezdve a telefonkészülékeken át a táblagépekig többféle hardveren működjön. 9

A DOLGOZAT ESZKÖZRENDSZERÉNEK RÖVID ÁTTEKINTÉSE Határidő Definíció (Határidő). A szoftver termék a megadott határidőre (vagy előtte) elkészül. Egy későn kiadott szoftver lehet, hogy teljesen feleslegessé válik. Ez nem csak a szoftveriparban van így, azonban ebben az ágazatban - lévén az egyik legdinamikusabban változó terület - a probléma fokozottan jelentkezik. Nagyobb szoftverrendszerek esetében a pontosság elég ritka dolognak számít, ezen a problémán agilis módszertanok [63], különleges fejlesztési eljárások [7] alkalmazásával igyekeznek enyhíteni a szoftverkészítéssel foglalkozó cégek. További külső minőségi mutatók A teljesség igénye nélkül álljon itt néhány további külső minőségi mutató! Tesztelhetőség: mennyire könnyű a tesztadatok előállítása. Integritás: mennyire biztosítottak a rendszer részei jogosulatlan felhasználás ellen. Javíthatóság: mennyire könnyű a hibák kijavítása. (Amennyiben a javítás egyszerűen kivitelezhető, a felhasználóknak kevesebb ideig kell együtt élni a hibával.) Gazdaságosság: a szoftver kifejlesztésének a költsége nem lépi túl a megadott keretet. 1.1.2. Belső szoftverminőségi mutatók Meyer azt állítja, hogy végső soron mindenképpen a külső tényezők számítanak; azonban a belső minőségből, illetve az ezt biztosító technikák alkalmazásából következik a külső minőségi mutatók javulása is. Ezt a nézetet osztják a szoftvermetrikák azon hívei is, akik a termék belső tulajdonságainak mérésétől és kontrollálásától várják áttételesen a használhatóság, tehát a külső minőség pozitív változását [45]. Az elképzelés azért különösen vonzó, mert a belső jellemzők alapján objektív és környezettől független képet kaphatunk a minőségről. Ugyanakkor a belső minőségből következő külső minőség inkább csak intuíció, mintsem tudományosan igazolt tétel. További kutatás tárgyát kell képezze annak a kiderítése is, hogy melyek azok a belső minőségi mutatók (amennyiben vannak ilyenek), amelyek közvetlenül befolyásolják a külső minőséget. A belső és a külső minőség megfeleltetésére, leképezésére számos modell született [58]. Arra is van bizonyíték [53, 82], hogy a belső minőséget kitüntető technikák alkalmazásával csökkenthető a fejlesztés során felmerülő hibák száma. Ez áttételesen azt jelenti, hogy kevesebb időt kell hibajavításra fordítani, következésképpen több idő marad a funkcionalitás kidolgozására. Ebből természetesen következik a külső minőség javulása is. 10

1.2. PROGRAMOK HELYESSÉGE 1.2. Programok helyessége A 1.1.1. szakaszban áttekintettem a fontosabb külső és belső szoftverminőségi mutatókat. Kiemeltem, hogy az egyik legfontosabb külső minőségi mutató a helyesség. Ebben a szakaszban az objektumorientált programok helyességfogalmával és az Eiffel helyességi specifikációs mechanizmusával foglalkozom. Programok helyességének ellenőrzésére a leggyakrabban alkalmazott módszer a tesztelés. Ezzel összhangban, dolgozatom 3. fejezetében a programhelyesség-ellenőrző infrastruktúra új alkalmazási területeként az axiomatikus specifikáción alapuló tesztelést mutatom be. A másik lehetőség, hogy a program kipróbálása, futtatása nélkül, matematikai eszközök felhasználásával megkíséreljük bizonyítani a program helyességét. Ez az eljárás már egyszerű programok esetén is meglehetősen nehéz feladat [34]. Az Eiffel programozási nyelv [72, 73] érdekes kevert megközelítést választott: a programhelyesség-ellenőrzéssel kapcsolatos elméleti elemeket közvetlenül beemelte a nyelv specifikációjába. Ezzel lehetővé vált a programok helyességének futásidejű ellenőrzése [85]. A megközelítés rokonságot mutat az automatizált teszteléssel, a fő különbség az, hogy az ellenőrzés egy belső nyelvi mechanizmuson alapul, a tesztadatokat pedig maga a program szolgáltatja. (Dolgozatom 4. fejezetében ezt az észrevételt fogom felhasználni arra, hogy releváns tesztadatokból álló adatbázist építsek az axiomatikus teszteléshez.) 1.2.1. Objektumorientált programok helyessége Mind a tesztelés, mind a futásidejű ellenőrzés során arra keressük tehát a választ, hogy a program helyes-e. Vegyük azonban észre, hogy a helyesség összetett fogalom. Ránézve egy programra nem tudjuk eldönteni, hogy az helyes-e vagy sem. Annak érdekében, hogy a kód a fordítóprogram számára értelmezhető legyen, meg kell felelnie bizonyos formai szabályoknak - ennek megfelelően beszélhetünk szintaktikai értelemben vett helyességről. A program működésének megértéséhez tisztában kell lennünk a nyelvi szerkezetek jelentésével, azaz szemantikájával is. A helyesség eldöntéséhez a szintaxison és a szemantikán kívül szükségünk van annak a minél pontosabb leírására is, hogy mi az, amit elvárhatunk a programtól. Ezeket az elvárásokat összefoglalóan helyességi specifikációnak nevezzük. Általánosságban egy M művelet esetén az {E}M{U} Hoare-formulát alkalmazzuk jelölésre. E az M művelet előfeltétele, U pedig az utófeltétele. A Hoare-formula jelentése, hogy amennyiben az E predikátum igaz a művelet végrehajtása előtt, és az M műveletet végrehajtjuk, akkor az befejeződik, és befejeződése után igaz lesz az U predikátum. Ezen jelölések figyelembe vételével a tipikus objektumorientált struktúrák helyességének eldöntését a 1.1 algoritmikus leírás tartalmazza. 11

A DOLGOZAT ESZKÖZRENDSZERÉNEK RÖVID ÁTTEKINTÉSE 1.1. algoritmus: Programstruktúrák elméleti helyessége 1. Minden attribútum (objektum, változó) helyes. 2. Ciklusok helyessége. Jelölje INIT egy ciklus inicializáló blokkját, legyen BODY a ciklusmag, INV a ciklus invariánsa, VAR a termináló függvény, REQ logikai kifejezés, amely azt írja le, hogy a ciklus milyen feltételek mellett hajtható végre. Ekkor a ciklus pontosan akkor helyes a helyességi specifikációra nézve, ha az alábbi Hoare-formulák érvényesek: {REQ}INIT {INV } {REQ}INIT {V AR 0} {INV EXIT }BODY {INV } {INV EXIT V AR = v}body {0 V AR v} 3. Kivételkezelés. A kivételkezelés során a nyilvános metódusoktól azt várhatjuk el, hogy az osztály esetlegesen sérült konzisztenciáját visszaállítsák. Bertrand Meyer eredeti definíciója [72, 73] szerint M nyilvános metódus kivételkezelése akkor és csak akkor konzisztens, ha a kivételkezelő minden B ágára (amely nem retry utasítással ér véget) érvényes a következő Hoare-formula: {T rue}b{i} 4. Metódusok helyessége. M metódus esetén legyen B a metódus törzse, E az előfeltétele, U az utófeltétele, I pedig a tartalmazó osztály invariánsa. Az M metódus akkor és csak akkor helyes a helyességi specifikációra nézve, ha minden benne előforduló ciklus helyes, továbbá érvényes az alábbi: {E}B{U} 5. Osztályok helyessége. Egy C osztály akkor és csak akkor helyes a specifikációra nézve, ha konzisztens, és minden metódusa helyes. Jelölje D az osztály alapértelmezett értékeit leíró feltételt. Akkor mondjuk, hogy a C osztály konzisztens az I osztályinvariánsra nézve, ha minden E, U specifikációval rendelkező, nyilvános metódusra a következő formulák érvényesek: {D E}B{U I} {I E}B{U I} 12

1.2. PROGRAMOK HELYESSÉGE Az objektumorientált programok helyességét a 1.1. leírásban szereplő osztályok helyességfogalmára lehet visszavezetni. 1.1. definíció (Osztályok közötti kapcsolatok). Egy adott kódrészletben A osztály ügyfélként (client), B osztály kiszolgálóként (server) szerepel, ha A közvetlenül vagy közvetetten hivatkozik B valamely metódusára, attribútumára, avagy magára a B típusra. 1.2. definíció (Osztályok közötti függőségek). Azt mondjuk, hogy az A osztály megvalósítása függ a B osztálytól, ha van olyan környezet, amelyben A ügyfél, B pedig kiszolgáló. Jelölés: B f lezártat + f -al jelöljük. Az A + f megvalósítása függ az A osztálytól. A. A függőségi reláció reflexív és tranzitív. A reflexív tranzitív kifejezés pontosan azokat az osztályokat jelöli, amelyek 1.3. definíció (Programok helyessége). Legyen adott P program, amelynek végrehajtása C osztály példányosításával jár. A P program akkor és csak akkor helyes a specifikációra nézve, ha + f C osztályok mindegyike helyes. 1.2.2. Az Eiffel helyességi specifikációs nyelve Az Eiffel programozási nyelv a fenti értelemben vett helyességi specifikációnak a megfogalmazására ad közvetlen nyelvi eszközöket, illetve egy olyan belső mechanizmust, amely képes a helyességi specifikáció futásidejű ellenőrzésére. Kulcsszó from invariant variant check require ensure old strip invariant Jelentés Ciklus inicializáló blokkja. Ciklusinvariáns. Termináló függvény. Ellenőrzés a program tetszőleges pontján. Metódus előfeltétele. Metódus utófeltétele. Hivatkozás a végreahjtás előtti értékre. Hivatkozás az osztály további, a megadotton kiívül eső részére. Osztályinvariáns. 1.1. táblázat: Az Eiffel helyességi specifikációs nyelvének elemei A 1.1 táblázatban felsorolt kulcsszavak az Eiffel helyességi specifikációs nyelvének a nyelvi elemei. Maga a helyességi specifikációs nyelv az Eiffel egy valódi részhalmaza [85]. A 2.3. szakaszban látni fogunk egy egyszerű példát a helyességi specifikációs nyelv használatára. Ezen a ponton elég annyit megjegyeznünk, hogy a helyességi specifikációs nyelv segítségével szerződéseket fogalmazhatunk meg. A szerződés fogalma az üzleti életből vett metafora: az 13

A DOLGOZAT ESZKÖZRENDSZERÉNEK RÖVID ÁTTEKINTÉSE ügyfél és a szolgáltató megállapodnak egy szerződésben, amely a közöttük létrejövő üzleti természetű viszonyt szabályozza. A fogalom természetes módon kiterjeszthető a szoftverrendszerekre, ahol mind az ügyfél, mind a szolgáltató szerepét egy-egy szoftverkomponens veszi át. Az objektumorientált rendszerek granularitását figyelembe véve az Eiffel programozási nyelv esetében az a jellemző, hogy a helyességi specifikációs nyelv által megfogalmazható szerződések osztályokhoz, metódusokhoz, metódusok bemenő paraméter eihez vagy visszatérési érték eihez kötődnek. 1.3. Az aspektusorientált programozásról Annak érdekében, hogy a szerződések specifikálása a programozási környezetbe illeszkedjen, feldolgozása, betartatása pedig a fejlesztők számára transzparens módon történjen, az aspektusorientált programozás eszköztárát hívtam segítségül. 1.1. megjegyzés (Aspektusorientált programozás). Az aspektusorientált programozás az 1990-es években létrejött programozási paradigma. Életre hívásában fontos szerepe volt annak, hogy az objektumorientált modellezés/programozás számos fontos alkalmazási terület (pl. hálózati kommunikáció) absztrakcióját nem támogatja kellő mértékben, és az UML alapú [107] tervező és kódgeneráló eszközök csak részben alkalmasak a már meglevő rendszerekkel való integrációra [85]. Tekintsük át az aspektusorientált programozáshoz köthető alapfogalmakat! 1.4. definíció (Komponens). Olyan programegység, amely a rendszer funkcionális dekompozíciója során természetes módon előáll. A komponensek tulajdonképpen a hagyományos objektumorientált programozás során előálló egységek: osztályok, objektumok, metódusok. 1.5. definíció (Aspektus). Olyan programegység, amely a rendszer funkcionális dekompozíciója során nem áll elő természetes módon, azonban a rendszer viselkedését befolyásolja. 1.6. definíció (Aspektusorientált programozás). Az aspektusorientált programozás célja, hogy a rendszert felépítése során oly módon dekomponáljuk aspektusokká és komponensekké, amely lehetővé teszi a megfelelő absztrakciót és a rendszer hatékony kompozícióját. Az aspektusoreintált programozást támogató eszközök abban különböznek leginkább a hagyományos programozási nyelvektől, hogy lehetőséget adnak a komponensek és az aspektusok absztrakciójára, illetve ezek egyszerű összeillesztésére, összeszövésére (weaving) is. Jó példa az aspektusorientált programozási paradigma felhasználásával elegánsan megoldható feladatra: alkalmazások üzleti és hibanaplójának előállítása, jogosultságok 14

1.4. A.NET KERETRENDSZER ÁTTEKINTŐ ISMERTETÉSE ellenőrzése a végrehajtás előtt, központi kivételkezelési mechanizmus megvalósítása. Ezek a példák a saját fejlesztői gyakorlatomból származnak, holott még sohasem készítettem tisztán aspektusorientált programot. Az aspektusorientált programozás azonban tipikusan multiparadigmás módszer: a szoftver komponensei a hagyományos (objektumorientált) paradigma szerint készülnek, az aspektusokat pedig gyakran egy előfeldolgozó lépésben illesztjük be a kódba. 1.4. A.NET keretrendszer áttekintő ismertetése A.NET keretrendszer [75] első szabványos [30, 50] verziója 2002-ben, mintegy 7 évvel a Java [52] után, azonban gyakorlatilag azonos alapelveket követve jelent meg. Ebben a szakaszban - ahol lehetséges, a Java-val összehasonlítva - mutatom be a platform felépítését és alapvető szolgáltatásait. Az egyik legfontosabb közös elem egy virtuális futtató környezet megléte, amelyet a Java közösségben Java Virtuális Gépnek (Java Virtual Machine), a.net esetében pedig általános futtató környezetnek (Common Language Runtime, CLR) neveznek. A környezetek virtualizációja megköveteli valamely - a virtuális környezet architektúrájának megfelelő -,,gépi kód létezését is. A Java-nál ez az ún. bájtkód (byte code), a.net-nél pedig az általános köztes nyelv (Common Intermediate Language, CIL), vagy egyszerűen csak köztes nyelv (Intermediate Language, IL). Jelentős eltérés van viszont abban, hogy míg a Java virtuális gépe gyakorlatilag minden széles körben elterjedt operációs rendszeren elérhető (Windows bármely verziója, Mac OS X, Linux, Solaris), tehát gyakorlatilag platformfüggetlen; addig a.net futtató környezet kizárólag a Windows operációs rendszer különböző verzióin működik. A Java bájtkód jelentősége így már érthető: amennyiben biztosítjuk, hogy ugyanaz a magas szintű Java nyelvű kód ugyanarra a bájtkód szekvenciára forduljon, továbbá a Java virtuális gép különféle megvalósításai pontosan ugyanazt a szolgáltatás halmazt kínálják, úgy biztosított a platformfüggetlenség. A.NET a Windows operációs rendszerhez kötődik, tehát nem platformfüggetlen. Létezik ugyan platformfüggetlen implementációja (Mono projekt [77]), és kutatási célra használható nyílt forráskódú implementációja is (Rotor, [101]), azonban ennek ellenére a Java-hoz hasonló ipari platformfüggetlenségről nem beszélhetünk. Mi tehát a célja a virtualizált futtató környezetnek és az általános köztes nyelvi reprezentációnak? A válasz a nyelvfüggetlenség. A.NET környezet ugyanis több, mint 40 programozási nyelvet támogat (köztük a C# nyelvet [29, 49, 71]), amelyek mindegyike az általános köztes nyelvre fordul. A Microsoft ráérzett arra, hogy - legalábbis az általános magas szintű programozási nyelveket figyelembe véve - a fejlesztők ragaszkodnak az általuk már korábban elsajátított nyelvek használatához. Sokkal könnyebb ugyanis valakit rávenni arra, hogy térjen át az új platformra, 15

A DOLGOZAT ESZKÖZRENDSZERÉNEK RÖVID ÁTTEKINTÉSE ha nem kell ehhez egyúttal egy új programozási nyelvet is megtanulnia. Természetesen tudjuk, hogy még egy programozási nyelv magas szintű ismerete sem jelenti azt, hogy valaki az adott nyelven produktív, jó programozó. Mindehhez az is kell, hogy a programozó ismerje az adott nyelvhez (és sok esetben környezethez!) kapcsolódó, gyakran felmerülő programozási feladatok (fájlkezelés, hálózati kommunikáció, adatbázis-elérés, XML feldolgozás, szálak szinkronizációja, stb.) megoldása során használható programkönyvtár akat. Az alapvető osztálykönyvtár (Base Class Library, BCL) [3, 70] a.net igen jól átgondolt, gondosan megtervezett, sokféle szolgáltatást nyújtó programkönyvtára, amely a platform által támogatott nyelvek bármelyikéből azonos módon használható. A programozók számára (és az őket alkalmazó cégek számára) a platform másik vonzereje, hogy amennyiben elsajátítják a BCL szolgáltatásainak a használatát, egy másik nyelvre történő váltáskor csak a nyelv szintaxisát kell megtanulni. A BCL szolgáltatásait az 1.2. táblázatban foglaltam össze [93]. Szolgáltatás Alapszolgáltatások Adatbázis elérés XML Vastag kliens Vékony kliens Kommunikáció Munkafolyamatok kezelése Hálózati szolgáltatások Nagyvállalati szolgáltatások Biztonsági szolgáltatások Platformhívás Kapcsolódó technológiák Alaptípusok kezelése, gyűjtemények kezelése, I/O ADO.NET, Linq2SQL, Entity Framework XML DOM és navigátor kezelése, validációk (XSD), transzformációk (XSLT, XPath) Windows Forms, Windows Presentation Foundation ASP.NET, ASP.NET MVC, SilverLight Socket kommunikáció, webszolgáltatások, remoting, Windows Communication Foundation Workflow Foundation IP alapú kommunikáció, alapvető protokollok (Ftp, http, Dns, stb.) Message Queue, COM+ Kriptográfia, címtár elérés WinAPI függvények, COM 1.2. táblázat: A BCL szolgáltatásai A BCL szolgáltatásait tehát a platform bármely nyelvéből elérjük, és minden nyelv a köztes nyelvre fordul. Az IL egy alacsonyszintű, az assembly-re hasonlító nyelv, amely egy vermet használ az utasítások közötti adatátvitelre. Az IL utasításkészletében a szokásos logikai és aritmetikai műveletek mellett helyet kaptak a memória lefoglalását, a ki- és becsomagolást, illetve a metódushívásokat végző utasítások is. 16

1.4. A.NET KERETRENDSZER ÁTTEKINTŐ ISMERTETÉSE A gépfüggő, azaz natív kódra való fordítást futási időben az általános futtató környezet végzi el, innen származik az elnevezés: futásidejű fordítás (just-in-time compilation, JIT) 6. A.NET környezetben a futásidejű fordítás lusta algoritmus szerint működik. Egy típus (osztály) elérésekor csak az osztály szintű műveleteket kell elvégezni: inicializálni kell a statikus változók tárolásához szükséges memóriát a statikus memóriaterületen, és le kell fordítani az osztály statikus konstruktorát. A nem osztály szintű metódusokat az általános futtató környezet a hívás tényleges előfordulásakor fordítja natív kódra. A fordítás csupán az első hívás esetén történik meg, a lefordított kód a program futásának a befejeződéséig rendelkezésre áll (a program újbóli végrehajtása azonban már új fordítást igényel). A köztes nyelven íródott kód a magas szintű programozási nyelven írt kód lefordításakor jön létre. Az így kapott modult - amely hasonló a Java csomag (package) fogalmához - alkalmazásmodulnak vagy szerelvénynek (assembly) nevezzük. Amennyiben a modulokat több alkalmazás között is meg szeretnénk osztani, úgy azokat a globális alkalmazásmodul tár ban (Global Assembly Cache, GAC) helyezhetjük el. Ez az alapértelmezett hely, ahol a.net modulbetöltő először keresi a modulokat. Technikailag a globális alkalmazásmodul tár egy egyszerű könyvtár (c:\windows\assembly\gac_64\), azonban egy modul felvétele a tárba nem egyszerű másolással, hanem a gacutil parancssori eszközzel történik. Csak olyan modulok helyezhetők el a globális tárban, amelyek rendelkeznek erős név vel. Az erős név a modul nevéből, verziójából, kultúrájából, és erős nevű kulcsából (strong name key) tevődik össze, amely fordítás után már nem változtatható meg, ezzel biztosítva a rendszer integritását. Bármely, a platform által támogatott magas szinten íródott kódból előállítható egy ilyen köztes nyelvű kódot tartalmazó alkalmazásmodul, tehát az eredetileg különféle nyelveken íródott komponensek egymással képesek együttműködni. Az alkalmazásmodul tipikusan egy dll fájl, amely köztes nyelvű utasításokat tartalmaz. A köztes nyelvű utasításokon kívül helyet kaphat benne beágyazott erőforrás (embedded resource), amely lehet szöveges állomány, bináris kép, zene, stb. A beágyazott erőforrások használata akkor kézenfekvő, amikor statikus információt kell a modullal együtt szállítanunk, vagy nincs hatásunk a program telepítésének a menetére. A beágyazott erőforrások mellett az alkalmazásmodul metaadatokat is tartalmazhat. A metaadatok a kód egységeihez statikusan, fordítási időben kapcsolható adatok, amelyek az általuk,,dekorált kód viselkedését megváltoztathatják. A metaadatokat attribútumok segítségével kapcsolhatjuk a struktúrákhoz 7. Minden olyan osztály, amely direkt vagy indirekt módon a System.Attribute BCL-beli osztályból származik, attribútum osztály. Bár maga az alapkönyvtár is számos attribútumot tartalmaz (Serializable, ServiceContract, Obsolete, stb.), természetesen saját attribútumok készítésére is van lehetőség. 6 A Java virtuális gép legtöbb megvalósítása is képes a futásidejű fordításra (Java HotSpot). 7 A Java-ban ugyanezt annotációk segítségével tehetjük meg. 17

A DOLGOZAT ESZKÖZRENDSZERÉNEK RÖVID ÁTTEKINTÉSE.NET Java Platformfüggetlenség Nyelvfüggetlenség Köztes nyelv (IL) (bájtkód) Futásidejű fordítás Közös típusrendszer - Közös osztálykönyvtár - Memóriakezelés, szemétgyűjtés Kivételkezelés Szálkezelés Kód metaadat (attribútum) (annotáció) Reflexió 1.3. táblázat: A.NET és a Java környezet összehasonlítása Az attribútum tehát egy közönséges osztály. Azonban mivel az attribútumnak átadott értékeknek fordítási időben ismert konstansoknak kell lenniük, a paraméterek típusa kizárólag az alábbi felsorolásban szereplő típusok közül kerülhet ki: bool, byte, char, double, float, int, long, short, string object System.Type enum (felsorolási típus), amennyiben nyilvános láthatóságú, és minden bennfoglaló típus (amennyiben van ilyen) is nyilvános láthatóságú A fenti típusokból képzett egydimenziós tömb típusok A fordítási időben a különféle programegységekhez kapcsolt attribútumok a reflexió segítségével kérdezhetők le futási időben 8. Az attribútumok futási időben közvetlenül nem módosíthatók. Az eddigiek alapján nyilvánvaló, hogy a.net és a Java igen hasonló koncepció, ezt szemléltetem a 1.3. táblázatban. 1.5. Függőségek injektálása 1.7. definíció (Fordított vezérlés). A fordított vezérlés ( inversion of control, IoC) a szoftverkészítés során alkalmazott architekturális tervezési alapelv. Nevét onnan kapta, hogy az alapelv alkalmazásával készült szoftver bizonyos végrehajtási lépései felcserélődnek a procedurális 8 A Java programozási nyelv annotációi egy szintén reflexiónak nevezett eljárás segítségével érhetők el. 18

1.5. FÜGGŐSÉGEK INJEKTÁLÁSA programozás során megszokott, az egyszerű probléma dekompozíción alapuló analízis és szintézis során előálló procedurális program végrehajtási lépéseihez képest. A fordított vezérlés tehát egy általános alapelv. A fogalom szemléltetésére tekintsünk egy konkrét példát! Tegyük fel, hogy feladatunk egy objektumorientált rendszer tervezése és megvalósítása. Tudjuk, hogy az objektumelvű rendszer egy dinamikus, irányított gráfnak tekinthető, amelynek csúcsai az objektumok, élei pedig az objektumok közötti kapcsolatokat, interakciókat szemléltetik [98]. A probléma megoldása objetumok interakciójának sorozataként áll elő. Amennyiben a gráfban két objektum között vezet (irányított) él, a két objektum között függőség áll fenn. Ez azt jelenti, hogy az aktív objektum hivatkozik a passzív objektumra vagy műveletet hajt rajta végre. A kérdés a passzív objektum létrehozásának a felelőssége: igaz-e, hogy a passzív objektumot az aktív objektumnak kell előállítania? A válasz - feltéve, hogy a passzív objektum kizárólag a fenti gondolatmenetben szereplő aktív objektummal kerül kölcsönhatásba - igenlő. Ezt a nézetet erősíti a felelősségek elosztásának általános ajánlásrendszere is [64], amely szerint az aktív objektumé a passzív példányosításának a felelőssége, ha rendelkezik minden adattal, amely alapján ezt megteheti, vagy szorosan csatolt a passzív objektummal. Sajnos, a példányosításhoz Az aktív objektumnak tudnia kell, hogy a passzív objektum milyen módon példányosítható. A passzív objektum példányosítási módjának változása hatást gyakorol az aktív objektumra. Az aktív objektum kódját beszennyezi az összes külső függőségének példányosításához kapcsolódó logika. Martin Fowler [35] munkájában ezen problémakörről, a fordított vezérlésről és a függőségek injektálásáról értekezik. 1.8. definíció (Függőségek injektálása). A függőségek injektálása egy, az objektumorientált szoftverkészítésben széles körben alkalmazott programtervezési minta. A minta alapján minden olyan objektumnak, amely a rendszer működése során bármikor,,aktív, és működését külső függőségek segítségével valósítja meg, nem kell tudnia a külső függőségek megvalósításáról, létrehozási módjáról. Helyette elegendő felsorolnia a külső függőségeit, azt, hogy azoktól milyen szerződés betartását várja el. Ezek a függőségek aztán - a tényleges végrehajtás előtt - beállíthatók, injektálhatók. 19

A DOLGOZAT ESZKÖZRENDSZERÉNEK RÖVID ÁTTEKINTÉSE 1 // Függöségek injektálása nélkül 2 public class PrettyPersonPrinter 3 { 4 public void PrintTallPeople () 5 { 6 var personfilterer = new PersonFiltererService (); 7 8 foreach ( Person p in personfilterer. GetTallPeople ()) 9 { 10 Console. WriteLine ( 11 String. Format (" Name : {0}, Height : {1} ", 12 p.name, p. Height )); 13 } 14 } 15 } 16 17 // Függöségek injektálva a konstruktorban 18 public class PrettyPersonPrinter 19 { 20 private readonly IPersonFiltererService _personfilterer ; 21 22 public PrettyPersonPrinter ( IPersonFiltererService personfilterer ) 23 { 24 _personfilterer = personfilterer ; 25 } 26 27 public void PrintTallPeople () 28 { 29 foreach ( Person p in _personfilterer. GetTallPeople ()) 30 { 31 Console. WriteLine ( 32 String. Format (" Name : {0}, Height : {1} ", 33 p.name, p. Height )); 34 } 35 } 36 } 1.1. kódrészlet: Függőségek injektálása A függőségek injektálása a fordított vezérlés kevésbé általános előfordulási formája. A szokásos végrehajtási sorrend - 1. aktív objektum megkapja a vezérlést, 2. példányosítja a függőséget, 3. a függőség segítségével megvalósítja a működést - megváltozik: a függőségek példányosítása már az előtt megtörténik, hogy az aktív objektum megkapná a vezérlést. A fogalom szemléltetésére tekintsük a 1.1. példát! A magas emberek listáját nyomtatjuk ki a PrettyPersonPrinter osztály PrintTallPeople metódusa segítségével. 20