Szoftverparadigmák és metrikák Porkoláb Zoltán ELTE IK Programozási Nyelvek és Fordítóprogramok tszk. http://gsd.web.elte.hu
Szoftvertechnológiai Fórum Az előadás vázlata Paradigmák és metrikák Új paradigmák Hogyan és miért csalnak a metrikák? Egy paradigma-független metrika 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Köszönet ELTE Informatikai Kooperációs Kutatási és Oktatási Központ (IKKK) dr. Balla Katalin dr. Kovács Attila Doktoranduszok Pataki Norbert Sipos Ádám … és mások 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Szoftver metrikák A fejlesztési folyamat mérése (process) A termék mérése (product) Külső mértékek Megbízhatóság, funkcionalitás, teljesítmény, … Belső mértékek Méret Stílus Bonyolultság … 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Paradigma Absztrakció Általános kiemelése Specifikus elhagyása Paradigma Útmutató az absztrakciók létrehozásához Szabályok és konvenciók Eszközök Folyamatos evolúció 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Assembly Gépi kód automatikus generálása Mesterséges redundancia Fordítóprogram (1952, Mark I. Autocoder) 1:1 leképezés gépi kódra Gyengének bizonyult a kód és a programozó hordozhatósága szempontjából 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Méret metrikák Forrásfájlok Modulok Alprogramok Sorok (LOC, eLOC) Utasítások Szavak Bájtok 2007. május 16. Szoftvertechnológiai Fórum
Automatikus programozás Számítások automatikus elvégzése A = B + C * D Gépfüggetlen magasszintű nyelv Gépfüggő kód automatikus generálása Hatékony fordítás (FORTRAN, 9:10) Gyengének bizonyult a kód megbízhatósága és karbantarthatósága szempontjából 2007. május 16. Szoftvertechnológiai Fórum
Strukturális bonyolultság Thomas J. McCabe 1976. FORTRAN programok tesztelési költsége Modularizáció támogatása IBM javaslat: Max 50 sor 25 IF THEN utasítás 33.5 független végrehajtási ágat jelentene 2007. május 16. Szoftvertechnológiai Fórum
McCabe ciklomatikus szám Független vezérlési utak száma Vezérlési gráf G = (E,N) |E|=e |N|=n V(G) = e – n + 2k (k komponens esetén) Erősen összefüggő gráfban a lineárisan független körök száma V(G) Összefüggő gráfokra V(G) = p + 1, p a predikátumok száma 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Példa a b d c e f V(G) = e – n + 2k = 9 – 6 + 2 = p + 1 = 4 + 1 = 5 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum McCabe ajánlásai Kódhossz helyett V(G) mérése Legyen V(G) < 10 Kivéve esetszétválasztás Megfigyelés: jó programozók 3..7 között Hibás kódok bonyolultsága gyakran 30..50 Strukturált programozás, GOTO esetenként megengedhető (Knuth) 2007. május 16. Szoftvertechnológiai Fórum
Strukturált programozás Szekvenciából, elágazásból és ciklusból felépülő (goto mentes) eljárások Paraméterátadással és globális változókkal kommunikálnak egymással Adekvát algoritmusok meghatározása Magasszintű függvénykönyvtárak Gyengének bizonyult az adatstruktúrák létrehozásában és kompozíciójában 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Információ-áramlás Sallie Henry, Dennis Kafura 1981. Információ útja: A hívja B-t (paraméterátadással) B visszatér értékkel, amit A felhasznál B output változót használ fan-in = belépő információ + érintett adat fan-out = kilépő információ + érintett adat C = méret * (fan-in + fan-out)2 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Halstead mérték Maurice Halsted 1982. Software–science metrics N1 operátorok összes száma N2 operandusok összes száma n1 egyedi operátorok száma n2 egyedi operandusok száma 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Halstead mérték 2. Programszótár n = n1 + n2 Programhossz N = N1 + N2 = n1 log2n1 + n2 log2n2 Program tárhely mérete (volume) V = N log2n Absztrakciós szint V* = LV = konstans L = V*/V Szükséges erőfeszítés (effort) E = V/L = V2/V* 2007. május 16. Szoftvertechnológiai Fórum
Strukturált programok Blokkszerkezet, beágyazási mélység James W. Howatt, Albert L. Baker 1989. Predikátum csomópont hatóköre Utasítás predikáló halmaza ND(G) = a gráf beágyazási mélysége SN(G) = N + ND(G) Nem csak strukturált programokra definiált 2007. május 16. Szoftvertechnológiai Fórum
Moduláris programozás Niklaus Wirth: Algoritmusok+Adatstruktúrák = Programok Adatszerkezetek: Pascal Modul, típus fogalom: Modula-2, Oberon Adatelrejtés, interfész és implementáció szétválasztása Gyengének bizonyult a kód újrafelhasználásának szempontjából 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum 80-as évek eleje Nagy team-ek, >106 kódsor Nehézkes a kommunikáció az eljárások között Adatszerkezetek és eljárások elszakadnak Felülről lefelé építkezik, nehezen újrafelhasználható a kód Megjelennek a „garázscégek” Kis fejlesztőkapacitás Azonnali produkciós kényszer Kód újrafelhasználás, komponensek igénye Alulról felfelé építkezés 2007. május 16. Szoftvertechnológiai Fórum
Objektum-orientált programozás Osztályok = újrafelhasználható modulok Öröklés Polimorfizmus Új nyelvek Simula 67 Smalltalk C++ = Algol68 + Simula67 Eiffel, Java, C#, … 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum OO metrikák Shyam R. Chidamber, Chris F. Kemerer Metódusok súlyozott bonyolultsága McCabe Öröklési hierarchia mélysége Nehezebb a viselkedés jóslása Közvetlen leszármazottak száma Rossz absztrakció Válasz egy üzenetre Nehezebb tesztelhetőség 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum OO metrikák 2. Osztályok közötti összefonódás Rossz absztrakció Sérülékeny szerkezet Kohézió hiánya osztályon belül eLOC Smalltalk: 8 eLOC/func C++ 24 eLOC/func 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Problémák McCabe érték alacsonyabb, mint strukturált programok esetében Függvény túlterhelés Virtuális függvények Set/get függvények torzítanak Öröklési hierarchia Absztrakt osztályok, interfészek Konvenciók 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Problémák 2. Operátor-túlterhelés torzít Kivételkezelés torzít String EvaluateSalaryAndReturnName( Employee e ) { if( e.Title() == "CEO" || e.Salary() > 100000 ) cout << e.First() << " " << e.Last() << " is overpaid" << endl; } return e.First() + " " + e.Last(); 23 végrehajtási ág! 2007. május 16. Szoftvertechnológiai Fórum
Objektumelvű paradigma kritikája Minden objektum? Hatékonyság vs. „elvszerűség” Pozitív és negatív változások Kifejezés probléma Egy osztályhierarchia nehezen bővíthető egyszerre új adatszerkezetekkel és új metódusokkal (Visitor pattern) 2007. május 16. Szoftvertechnológiai Fórum
Új paradigmák Funkcionális programozás újraéledése Aspektusorientált programozás Generikus programozás (Template) metaprogramozás Szándékelvű programozás Multiparadigma elvű rendszerek Az új paradigmák beépítik a korábbi paradigmák tapasztalatait és eszközeit 2007. május 16. Szoftvertechnológiai Fórum
Funkcionális programozás Kompozicionalitás elve, függvénykiértékelés Lambda kalkulus, gráfátíró rendszerek Magasabbrendű függvények, típusok Hivatkozási helyfüggetlenség Optimalizáció, párhuzamos végrehajtás Scheme, ML, sML, Miranda, OCaml, Haskell, Clean 2007. május 16. Szoftvertechnológiai Fórum
Funkcionális - Hogyan mérjük? Nincsen utasítás Nincsen vezérlőszerkezet Rekurziós mélység – futási időben derül ki Fastruktúra Végtelen adattípusok Lusta kiértékelés 2007. május 16. Szoftvertechnológiai Fórum
Aspektus-orientált programozás Motiváció: rossz modularitás OOP-ban Szétszórt kódrészletek nehéz karbantartása Program = Osztályok+Aspektusok+Csatolási pontok AspectJ 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum AOP – Hogyan mérjük? AOP = OO + csatolási pontok Példa: void f(int) throws IOException ( void || int f(*) ) throws (A || B) * *(*) throws * Additív vagy multiplikatív? 2007. május 16. Szoftvertechnológiai Fórum
Generikus programozás Adatszerkezetek + általános algoritmusok Fordítási idejű típusellenőrzés Parametrikus polimorfizmus Functorok = algoritmusok, mint osztályok Példa: C++ Standard Template Library Kiindulunk egy konkrét kódból és a hatékonyság elvesztése nélkül általánosítunk 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum int *find( int *beg, int *end, int x) { while ( beg != end ) if ( *beg == x ) return beg; ++beg; } return 0; int t[10] = { 2, 5, 6, …, 88 }; int *p = find( t, t+10, 99); 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum template <typename T> T *find( T *beg, T *end, T x) { while ( beg != end ) if ( *beg == x ) return beg; ++beg; } return 0; const double t[10] = {2.1,5.3,6.1, …,88.2}; const double *p = find( t, t+10, 99.9); 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum template <typename It, typename T> It find( It beg, It end, T x) { while ( beg != end ) if ( *beg == x ) return beg; ++beg; } return end; vector<double> vd; vd.push_back(3.14); vector<double>::const_iterator vdi = find( vd.begin(), vd.end(), 99.9); 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum template <typename It, typename P> It find_if( It beg, It end, P p) { while ( beg != end ) if ( p(*beg) ) return beg; ++beg; } return end; vector<int> vi; vi.push_back(3); … bool div3(int i) { return i%3 == 0; } vector<int>::const_iterator vci = find( vi.begin(), vi.end(), div3); 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum struct divNthX { divNthX(int n,int x):N(n),X(x),cnt(0) {} bool operator()(int i) if ( i%X == 0) ++cnt; return N == cnt; } int cnt, int N, int X; }; vector<int> vi; vi.push_back(3); … vector<int>::const_iterator vci = find(vi.begin(),vi.end(),divNthX(i,j)); 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum GP – Hogyan mérjük? int main() { string s1, s2; ifstream f1("file1.txt"); ifstream f2("file2.txt"); f1 >> s1; f2 >> s2; while (f1 || f2) if (f1 && ((s1 <= s2) || !f2)) { cout << s1 << endl; } if (f2 && ((s1 >= s2) || !f1)) { cout << s2 << endl; Méret metrika? McCabe? int main() { ifstream if1("file1.txt"); ifstream if2("file2.txt"); merge( istream_iterator<string>(if1), istream_iterator<string>(), istream_iterator<string>(if2), istream_iterator<string>(), ostream_iterator<string>(cout,"\n") ); } 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum GP – Hogyan mérjük? 2. Információ-áramlás? find_if( v.begin(),v.end(),pred()); sort( v.begin(),v.end(),greater<int>()); 2007. május 16. Szoftvertechnológiai Fórum
C++ template metaprogramozás 1994, template-ek szabványosítása unruh.cpp 30: conversion from enum to D<2> requested unruh.cpp 30: conversion from enum to D<3> requested unruh.cpp 30: conversion from enum to D<5> requested unruh.cpp 30: conversion from enum to D<7> requested unruh.cpp 30: conversion from enum to D<11> requested unruh.cpp 30: conversion from enum to D<13> requested unruh.cpp 30: conversion from enum to D<17> requested unruh.cpp 30: conversion from enum to D<19> requested Fordítási időben Turing-teljes 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum int factorial( int n) { return (n==0) ? 1 : n*factorial(n-1); } int main() { cout << factorial(5) << endl; return 0; template <int N> struct Factorial { enum { value = N * Factorial<N-1>::value }; }; template <> struct Factorial<1> { enum { value = 1 }; const int fact5 = Factorial<5>::value; std::cout << fact5 << endl; 2007. május 16. Szoftvertechnológiai Fórum
Template metaprogramozás 2. Fordítási idejű optimalizálások Aktív könyvtárak Döntések elhalasztása Futási idejű hibák elkerülése Típusrendszer kiterjesztése Hogyan mérjük? 2007. május 16. Szoftvertechnológiai Fórum
Szándékalapú programozás Charles Simonyi XEROX Palo Alto Bravo Microsoft Word, Excel Intentional Software http://www.intentsoft.hu 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Jelenlegi helyzet Feladat-specifikus tudás Programozó Forráskód Futtatás ? 20 000 oldal 200 oldal 19 800 oldal Szoftverfejlesztői tudás? 2007. május 16. Szoftvertechnológiai Fórum
Szándékalapú programozás 2. Feladat-specifikus tudás Domain kód Forráskód Futtatás 200 oldal 20 000 oldal Generátor Programozó 10 000 oldal Hogyan mérjük? 2007. május 16. Szoftvertechnológiai Fórum
Paradigma-független metrika Strukturális bonyolultságon kell alapulnia Nem használhat paradigmafüggő fogalmakat Figyelembe veszi: A fordítási idejű döntéseket A végrehajtás bonyolultságát Az adatok (típusok) bonyolultságát 2007. május 16. Szoftvertechnológiai Fórum
Egy paradigma-független metrika smain P1 tmain b P4 a c d1 d3 d4 d2 data node output node input node 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Függvény létrehozása smain P1 tmain b P4 a c d1 d3 d4 d2 smain P1 tmain b e c d1 d3 P4 a d4 d2 se te 2007. május 16. Szoftvertechnológiai Fórum
Osztály bonyolultsága sset_next_month P1 tsnm b a c sset_next_day P2 e P3 g f P4 d1 d3 d2 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Összefoglalás A paradigmák evolúcióját tapasztaljuk A metrikák fejlődése ezt késve követi Paradigmafüggő metrikák erősen torzítanak más paradigmájú programon Egyre többször használunk több paradigmát együtt, ezért Igény van paradigma-független metrikákra 2007. május 16. Szoftvertechnológiai Fórum
Szoftvertechnológiai Fórum Irodalom McCabe, T.J., A Complexity Measure, IEEE Trans. Software Engineering, SE-2(4), pp. 308-320, 1976 Piwowarski, R.E.: A Nesting Level Complexity Measure, ACM Sigplan Notices, 17(9), pp.44-50, 1982 Porkolab, Z., Sillye, A.: Comparison of Object-Oriented and Paradigm Independent Software Complexity Metrics, ICAI'04, Eger, 2004 Porkolab, Z., Sillye, A.: Towards a multiparadigm complexity measure, QAOOSE Workshop, ECOOP, Glasgow, pp.134-142, 2005 Power, J. F., Malloy, B. A.: A metrics suite for grammar-based software. Journal of Software Maintenance 16(6): 405-426 (2004) Schmidmeier, A., Hanenberg S., Unland, R.: Implementing Known Concepts in AspectJ, 2003 Seront, G., Lopez, M., Paulus, V., Habra, N.: On the Relationship between Cyclomatic Complexity and the Degree of Object Orientation, QAOOSE Workshop, ECOOP, Glasgow, pp. 109-117 Wadler, P.: The expression problem, Posted on the Java Genericity mailing list, 1998 Weyuker, E.J.: Evaluating software complexity measures, IEEE Trans. Software Engineering, vol.14, pp.1357-1365, 1988 Cardelli, L., Wegner, P.: On Understanding Types, Data Abstraction, and Polymorphism, ACM Computing Surveys 17(4), pp. 471-522, 1985 Chidamber S.R., Kemerer, C.F., A metrics suit for object oriented design, IEEE Trans. Software Engeneering, vol.20, pp.476-498, (1994). Figueiredo, E., Garcia, A., Sant' Anna, C., Kulesza, U., Lucena, C.: Assessing Aspect-Oriented Artifactsd: Towards a Tool-Supported Quantitative Method, QAOOSE Workshop, ECOOP, Glasgow, pp. 58-69, 2005 Guyomarc'h, J-Y., Gu\'eh\'eneuc, Y-G.: On the Impact of Aspect-Oriented Programming on Object-Oriented Metrics, QAOOSE Workshop, ECOOP, Glasgow, pp. 42-47, 2005 Harrison, W.A., Magel, K.I., A Complexity Measure Based on Nesting Level, ACM Sigplan Notices,16(3), pp.6 Howatt, J.W., Baker, A.L.: Rigorous Definition and Analysis of Program Complexity Measures: An Example Using Nesting, The Journal of Systems and Software 10, pp.139-150, 1989 Kiczales, G., Hilsdale, E., Hugunin, J., Kersten, M., Palm, J., Griswold, W.G.: An Overview of AspectJ, LNCS vol. 2072, pp. 327-355, 2001 Kiczales G., Henneman, J.: Design Pattern Implementation in Java and AspectJ,OOPSLA, pp. 161-173, 2002 Kiczales, G.: Aspect-Oriented Programming, AOP Computing surveys 28(es), 154-p, 1996 2007. május 16. Szoftvertechnológiai Fórum
Köszönöm a figyelmet! Kérdések? Porkoláb Zoltán ELTE IK Programozási Nyelvek és Fordítóprogramok tszk. http://gsd.web.elte.hu 2007. május 16. Szoftvertechnológiai Fórum