Słowa kluczowe: obiektowe metryki oprogramowania, model predykcji błędów, jakość, wytwarzanie oprogramowania. Marian Jureczko * Ocena jakości obiektowo zorientowanego projektu programistycznego na podstawie metryk oprogramowania ** Praca opisuje przeprowadzony w warunkach akademickich eksperyment, którego celem była próba konstrukcji modelu ilustrującego zależności pomiędzy wartościami metryk oprogramowania a jakością programu. Badano zarówno metryki wyliczane z kodu źródłowego programu, tu mowa o takich metrykach jak: LCOM, CBO, RFC, WMC, DIT, NOC, jak i metryki wyliczane z diagramów języka UML, a mianowicie: NATC1, NATC2, NOPC1, NOPC2, NASC, DIT, NSUBC. Badania miały na celu znalezienie zależności pomiędzy wartościami metryk a czasem jaki należy poświęcić na naprawienie, znalezionych podczas testów, błędów w kodzie źródłowym klasy dla której metryki wyliczano. Środowisko eksperymentu stanowiły cztery podobne, zarówno pod względem tematyki jak i rozmiaru, projekty realizowane przez programistów o zbliżonym doświadczeniu. Do implementacji wykorzystywano obiektowe języki programowania: C# i java. 1. WPROWADZENIE W procesie wytwarzania oprogramowania istnieje bardzo silna zależność pomiędzy czasem wykrycia błędu a kosztami związanymi z jego usunięciem. Im później błąd zostanie wykryty tym większe są koszty jego eliminacji. Zazwyczaj w literaturze zaleca się prowadzenie intensywnego testowania oraz kontroli jakości już od najwcześniejszych etapów realizacji projektu, w celu jak najwcześniejszego wykrywania wszystkich nieprawidłowości [12], [13], [15]. Można próbować wspomóc ten proces przez szacowanie poprawności elementu na podstawie niektórych jego cech. Prowadzi się liczne badania dotyczące predykcji jakości na podstawie metryk strukturalnych. Istnieje wiele różnych zestawów metryk odnoszących się do różnych, powstających w trakcie procesu wytwarzania oprogramowania artefaktów. Przy pomocy metryk próbuje się opisywać dokumenty ze specyfikacją systemu * Instytut Informatyki, Automatyki i Robotyki, Politechnika Wrocławska * * Praca naukowa finansowana ze środków na naukę w latach 2006-2007 jako projekt badawczy 3 T11C 061 30
[11] i [21]. Działania takie napotykają jednak poważne problemy powiązane z analizą języka naturalnego. Problemy te są szczególnie trudne do pokonania jeżeli dotyczą języka polskiego. Zdecydowanie bardziej obiecujące są prace dotyczące oceny jakości na podstawie metryk wyliczanych z modelu systemu. Opracowuje się specjalne zestawy metryk dedykowane do opisywania modelu wyrażonego w UML [16]. Dyskutuje się zasadność takiego podejścia [4], i co najważniejsze, w stosunku do pewnych specyficznych systemów, uzyskuje się już nawet ciekawe wyniki [18]. Najbardziej ugruntowane są jednak badania dotyczące predykcji błędów na podstawie metryk wyliczanych z kodu źródłowego. Spektakularne wyniki udało się uzyskać w [3]. W pracy tej próbowano zastosować, omówiony dalej, zestaw metryk CK Metrics [10] do wyliczenia prawdopodobieństwa istnienia w klasie błędu. Przeprowadzone badania wykazały istnienie znaczącej, dodatniej korelacji pomiędzy prawdopodobieństwem zajścia błędu, a wartościami metryk DIT, RFC i CBO oraz ujemnej korelacji pomiędzy prawdopodobieństwem zajścia błędu a wartością metryki NOC. W [8], opierając się na kilku różnych zestawach metryk (w sumie 49 metryk), udało się skonstruować model, który znajduje 95% błędów systemu natomiast 85% modułów, które model oznakowuje jako błędne, faktycznie zawiera błędy. Do predykcji jakości stosuje się również z powodzeniem metody zaczerpnięte z gruntu sztucznej inteligencji, takie jak sieci neuronowe [17]. Prowadzi się też badania mające na celu wskazać najlepiej nadający się do oceny jakości i predykcji defektów zestaw metryk [1], [8], [19]. Według [19] najlepszym takim zestawem jest wykorzystywany w tej pracy zestaw CK Metrics. Natomiast według [8], gdzie wybierano pojedyncze metryki z różnych zestawów, wśród metryk najlepiej nadających się do przewidywania jakości, powinny się znaleźć dwie metryki z zestawu CK Metrics: NOC i RFC. Innym badanym aspektem opisywania systemu przy pomocy metryk strukturalnych jest automatyczne pozyskiwanie wartości metryk [5], [7], [20]. Istnieje wiele narzędzi pozwalających na automatyzację tego procesu. Zdecydowana ich większość jest jednak dedykowana do wyliczania metryk z kodu źródłowego [5], [20]. Jedynie nieliczne pozwalają na wyliczanie metryk z diagramów stanowiących model systemu [7]. Poważnym problemem podczas automatycznego wyliczania metryk jest fakt, że różne narzędzia w różny sposób interpretują definicje poszczególnych metryk i tym samym mogą wprowadzać dodatkowe błędy do pomiarów. W ramach tej pracy została podjęta próba konstrukcji modeli dokonujących predykcji błędów w projekcie informatycznym na podstawie metryk strukturalnych. Zastosowano dwa podejścia. Pierwsze to tworzenie modeli opierających się na metrykach wyliczanych z kodu źródłowego (czyli podobne do przedstawionego w [3], [8] i [17]). Drugie natomiast to tworzenie modeli, opierających się na metrykach wyliczanych na podstawie diagramów UML stanowiących model systemu.
2. PLAN EKSPERYMENTU Eksperyment przeprowadzony został w środowisku akademickim. Opiera się on na czterech projektach programistycznych realizowanych przez studentów piątego roku informatyki. Każdy z projektów był wykonywany przez czteroosobowy zespół. Położony został duży nacisk na jakość w każdym z zespołów jedna z osób pełniła funkcję inspektora. Inspektor miał za zadanie wychwytywać błędy popełniane przez pozostałych członków zespołu, jego rola była oparta na zaleceniach przedstawionych w [13]. Drugą wyodrębnioną w każdym zespole funkcją była funkcja kierownika. Był on odpowiedzialny za organizację pracy i rozdzielanie zadań pomiędzy członków zespołu (w tym i siebie). Wszystkie cztery projekty były realizowane w tej samej metodyce zbliżonej bardzo do procesu kaskadowego. Na podobieństwo do tego procesu wskazuje między innymi harmonogram prac: Na początek przygotowywano specyfikację programu w języku UML. Kolejno konstruowano diagramy przypadków użycia, klas, sekwencji i stanów. Przy pomocy diagramów klas modelowano cały system, za wyjątkiem jego interfejsu graficznego. Natomiast diagramy sekwencji oraz stanów były konstruowane jedynie dla niektórych fragmentów tworzonego systemu. Na realizację tego etapu poświęcono cztery miesiące. Drugi etap to implementacja w jednym z obiektowych języków programowania. Trzy programy zostały zaimplementowane przy pomocy C#, jeden natomiast przy pomocy javy. Wykonanie tego etapu trwało trzy miesiące. Trzeci etap to testowanie i poprawianie znalezionych podczas testowania błędów. Testy przeprowadzali ci sami studenci, którzy realizowali omawiane projekty. Zorganizowano to jednak w taki sposób, że nikt nie testował swojego projektu, tylko któryś z realizowanych przez jedną z pozostałych grup. Testowanie rozpoczęło się równocześnie z poprawianiem błędów i trwało trzy tygodnie. Na poprawianie błędów przeznaczono natomiast cztery tygodnie. Podczas naprawiania błędów odnotowywano jaki czas poświęcono na tą czynność. Programy testowano na zasadzie czarnej skrzynki. Jako błędy, oprócz niepoprawnego funkcjonowania (w tym i niepoprawnego prezentowania danych), traktowano również niezaimplementowanie funkcjonalności, które według dokumentacji w programie powinny się pojawić. Nie uwzględniano natomiast kwestii związanych z wydajnością. Zmierzone na tym etapie czasy poświęcone na poprawienie błędów posłużyły jako wyjście (zmienna zależna) konstruowanych modeli. Wejściem (zmienne niezależne) modeli były wartości przedstawionych dalej metryk. Modele konstruowano przy pomocy regresji liniowej, do każdego wejścia dobierano taki współczynnik, aby suma wejść jak najlepiej przybliżała czas potrzebny na poprawienie błędów. Więcej szczegółów na temat konstrukcji modeli znajduje się w dalszej części pracy.
3. ZASTOSOWANE METRYKI Zastosowano odrębne zestawy metryk, do opisania atrybutów projektu programu wyrażonego diagramami UML oraz do programu już zaimplementowanego. 3.1. METRYKI WYLICZANE NA PODSTAWIE KODU ŹRÓDŁOWEGO Jako metryki wyliczane na podstawie kodu źródłowego wybrane zostały metryki zaproponowane w [10], popularnie nazywane CK Metrics. Poniżej zostały one pokrótce omówione, więcej szczegółów na ich temat można znaleźć w: [1], [2], [3], [9], [14] oraz [15]. Response For a Class (RFC, z ang. odpowiedź klasy): Jest to liczba metod, które mogą być wywołane w odpowiedzi na wiadomość odebraną przez obiekt danej klasy. Wyliczana jest przez zsumowanie wszystkich metod danej klasy oraz zbioru odpowiedzi, czyli metod z innych klas, które mogą zostać wywołane przez którąś z metod danej klasy. Depth of Inheritance Tree (DIT, z ang. głębokość drzewa dziedziczenia): Jest to ilość przodków danej klasy w najdłuższej ścieżce dziedziczenia. W skład ścieżki dziedziczenia wliczane były również klasy systemowe (dostarczane przez środowisko programistyczne), z których dana klasa dziedziczyła. Lack of Cohesion Of Methods (LCOM, z ang. brak spójności metod): Metryka ta wskazuje jak blisko metody są powiązane z atrybutami. Im większa wartość metryki tym słabsze powiązanie. Tutaj zastosowano tą metrykę w wersji zaproponowanej w [14]. Jej wartość wylicza się konstruując graf dwudzielny G(M,A,K). Wierzchołki ze zbioru M reprezentują metody klasy, a wierzchołki ze zbioru A atrybuty. K to zbiór krawędzi. Pomiędzy wierzchołkiem m i M, a wierzchołkiem a i A istnieje krawędź wtedy, gdy metoda m i korzysta z atrybutu a j, lub gdy metoda m i wywołuje inną metodę m k, która jest w grafie powiązana krawędzią z atrybutem a j. Dla tak skonstruowanego grafu wartość metryki wylicza się ze wzoru: k m LCOM = a 1 m (1) gdzie k to liczebność zbioru K, a to liczebność zbioru A, m to liczebność zbioru M. Więcej informacji o tej metryce można znaleźć w [14] metryka ta jest tam oznaczana symbolem: LCOM*.
Coupling Between Objects (CBO, a ang. powiązania pomiędzy obiektami): Metryka ta pokazuje jak silnie dana klasa jest powiązana z innymi klasami. Za powiązanie uznaje się odwołanie do metody lub pola zdefiniowanego w innej klasie. Wartość tej metryki jest równa liczbie klas, z którymi dana klasa jest powiązana. Przy wyliczaniu tej metryki brane są również pod uwagę klasy systemowe (dostarczane przez środowisko programistyczne). Weight Method per Class (WMC, z ang. ważona liczba metod w klasie): Jest to suma wszystkich metod zdefiniowanych w klasie, każda metoda jest sumowana z przyporządkowaną jej wagą. Tu każdej metodzie przyporządkowywano wagę równą jeden. Number of Children (NOC, z ang. liczba klas pochodnych): Metryka ta jest wyliczana jako liczba bezpośrednich podklas danej klasy w hierarchii dziedziczenia. 3.2. METRYKI WYLICZANE NA PODSTAWIE DIAGRAMÓW Do opisania modelu systemu wyrażonego przy pomocy diagramów UML wykorzystane zostały metryki zaproponowane w [16]. Niestety z niektórych z nich trzeba było zrezygnować. W szczególności trzeba było odrzucić wszystkie te, które wyliczane były na podstawie diagramów sekwencji. W badanych projektach diagramy sekwencji wykorzystano bowiem jedynie do modelowania niektórych interakcji. Wyliczanie na podstawie tych diagramów metryk dałoby więc przekłamane wartości. Z zestawu wybrano następujące metryki: Number of the attributes in a class - unweighted (NATC1, z ang. nieważona liczba atrybutów w klasie): Metryka zlicza liczbę atrybutów jaką posiada rozważana klasa. Number of the attributes in a class weighted (NATC2, z ang. ważona liczba atrybutów w klasie): Metryka zlicza liczbę atrybutów jakie posiada klasa. Każdy atrybut jest brany z odpowiednią wagą. Wartość wagi zależy od widoczności atrybutu. Atrybuty public i package mają wagę 1.0, protected mają wagę 0.5, a private 0. Number of the operations in a class unweighted (NOPC1, z ang. nieważona liczba metod w klasie): Metryka zlicza liczbę metod jaką posiada rozważana klasa. Number of the operations in a class weighted (NOPC1, z ang. ważona liczba metod w klasie): Metryka zlicza liczbę metod jakie posiada klasa. Każda metoda jest brana z odpowiednią wagą. Wartość wagi zależy od widoczności metody w sposób analogiczny jak w NATC2. Number of the associations linked to a class (NASC, z ang. liczba asocjacji powiązanych z klasą): Jest to liczba asocjacji przy pomocy których dana klasa jest powiązana z innymi klasami. Jako asocjacje liczone są również agregacje. Depth of Inheritance Tree (DIT, z ang. głębokość drzewa dziedziczenia): Jest to liczba przodków danej klasy w najdłuższej ścieżce dziedziczenia.
Number of subclasses of a class (NSUBC, z ang. Liczba podklas danej klasy): Jest to liczba bezpośrednich podklas danej klasy w hierarchii dziedziczenia. 4. UZYSKANE WARTOŚCI METRYK Aby można było rozróżnić poszczególne projekty zostały one oznaczone literami. Projektom realizowanym w języku C# przyporządkowano litery A, B i C natomiast projekt pisany w języku java został opatrzony literą D. Projekt A składa się z 48 klas, projekt B z 40 klas, projekt C z 39 klas, a projekt D z 23 klas. Łącznie przebadano więc 150 klas. Liczba klas w przypadku metryk wyliczanych z diagramów jest nieco mniejsza i wynosi 136. Jest tak ponieważ klasy związane z implementacją interfejsu graficznego nie zostały uwzględnione na diagramach. Proces wyliczania metryk z kodu źródłowego został zautomatyzowany poprzez zastosowanie specjalistycznych programów. W przypadku projektów wykonanych w języku C# wykorzystano do tego celu narzędzie NDepend. Natomiast w stosunku do projektu wykonanego w javie, do wyliczania metryk użyto dwóch narzędzi: Eclipse Metrics plugin oraz ckjm. 4.1. WARTOŚCI METRYK WYLICZANYCH Z KODU ŹRÓDŁOWEGO Max Min Średnia Mediana δ WMC 47 0 9,73 7,5 8,11 DIT 8 1 3,34 3 2,41 NOC 22 0 0,33 0 1,98 RFC 87 1 25,54 21 17,79 CBO 66 0 15,56 9 16,11 LCOM 2 0 0,67 0,88 0,45 Tabela 1: Wartości metryk kodu źródłowego Table 1: Values of source code metrics W tab. 1 przedstawione są wartości metryk dla wszystkich czterech realizowanych projektów. Na podstawie tych danych można odnieść wrażenie, że bardzo intensywnie wykorzystywany był mechanizm dziedziczenia o czym mogłaby świadczyć stosunkowo wysoka wartość metryki DIT. Jej wartość średnia jest około trzy razy większa niż jej wartość dla projektów badanych w [3] i [9]. Przekonanie takie jednak jest błędne, dziedziczenia było wykorzystywane bardzo umiarkowanie, a wysoka wartość tej metryki wynika z użytych w projektach języków (zarówno java, jak i C# wymuszają tworzenie klas, które mają przynajmniej jednego przodka; wymogu takiego nie ma w języku C++, który był wykorzystywany w projektach omawianych w [3] i [9]) oraz uwzględniania przy wyliczaniu tej metryki klas systemowych które, pojawiają się na ścieżce dziedziczenia. Na fakt stosunkowo małego wykorzystywania
dziedziczenia wskazuje niska wartość metryki NOC. Wartość średnia tej metryki pokazuje, że zdecydowana większość klas nie miała potomków. Wartość maksymalna, równa 22, dowodzi jednak, że były tworzone również klasy z myślą o tym, żeby zakotwiczyć w nich sporych rozmiarów drzewa dziedziczenia. Na złe praktyki programistyczne wskazuje stosunkowo duża wartość metryki CBO. Sytuacja taka sugeruje, że poprawianie błędów, może być obarczone sporym nakładem czasowym z uwagi na liczne zależności pomiędzy klasami. Max Min Średnia Mediana δ WMC 47 0 9,91 8 8,56 DIT 7 1 2,34 2 1,6 NOC 22 0 0,44 0 2,31 RFC 87 1 25,36 20 18,41 CBO 52 0 13,81 6 15,45 LCOM 2 0 0,6 0,8 0,48 Tabela 2: Wartości metryk kodu źródłowego dla klas implementacyjnych Table 2: Values of source code metrics for implementation classes Wśród klas można wydzielić dwie grupy zasadniczo różniące się wartościami metryk. Pierwsza, to klasy graficznego interfejsu użytkownika (wszystkie badane projekty posiadają graficzny, a nie tekstowy interfejs), natomiast druga, to klasy implementacyjne, czyli wszystkie pozostałe. Porównując wartości metryk wyliczonych dla klas implementacyjnych z wartościami metryk wyliczonych dla wszystkich klas, najłatwiej zauważyć różnicę pomiędzy wartościami metryk NOC i DIT. W klasach implementacyjnych metryka DIT przyjmuje zdecydowanie niższe wartości. Co wskazuje na to, że klasy te rzadko dziedziczyły po specjalizowanych klasach systemowych (zazwyczaj dziedziczyły Max Min Średnia Mediana δ WMC 34 1 9,54 8 6,88 DIT 8 1 6,18 7 2,08 NOC 2 0 0,05 0 0,32 RFC 64 4 27,18 30 15,79 CBO 66 0 20,87 17 17,21 LCOM 2 0 0,86 0,92 0,32 Tabela 3: Wartości metryk kodu źródłowego dla klas gui Table 3: Values of source code metrics for gui classes tylko po klasie Object, co dawało wartość metryki DIT równą jeden). Metryka NOC natomiast przyjmuje wartość większą niż dla zbioru wszystkich klas. To z kolei świadczy o tym, że jeżeli już stosowano mechanizm dziedziczenia to zazwyczaj dziedziczono po klasach tworzonych na potrzeby projektu, a nie po klasach systemowych. Powstawały więc hierarchie dziedziczenia projektowane na potrzeby danego projektu. Warto również zauważyć, że nieco mniejszą wartość przyjmuje tu metryka CBO.
W klasach składających się na graficzny interfejs użytkownika bardzo wysoka jest wartość metryki DIT. Jej wartość średnia to aż 6,18. Jest tak, ponieważ większość klas z tej grupy dziedziczy po wyspecjalizowanych klasach systemowych komponentach interfejsu graficznego. Bardzo niska za to jest wartość metryki NOC - po klasach wchodzących w skład tej grupy raczej już nie dziedziczono. Stosunkowo duża jest wartość metryki CBO, jej średnia wynosi 20,87, kiedy dla wszystkich klas jej średnia to 15,56. Okazuje się więc, że bardzo duże uzależnienie od innych klas wykazują głównie klasy interfejsu graficznego. 4.2. KORELACJA METRYK WYLICZANYCH Z KODU ŹRÓDŁOWEGO WMC DIT NOC RFC CBO LCOM WMC 1 0,06 0,01 0,25 0,6 0,2 DIT 1-0,12-0,03 0,21 0,37 NOC 1 0,02-0,05 0,01 RFC 1 0,45-0,05 CBO 1 0,14 LCOM 1 Tabela 4: Macierz korelacji - wartości metryki z wszystkich projektów Table 4: Correlation matrix values of metrics for all projects W publikacjach [3] i [9] badając zestaw metryk zaproponowany w [10] rozważano korelację pomiędzy wartościami poszczególnych metryk. Niezwykle ciekawy jest również fakt, że w pracach tych (tj. [3] i [9]) uzyskano przeciwstawne rezultaty. Z obliczeń przeprowadzonych w [3] wynika, że rozważane metryki nie są skorelowane. Natomiast w [9] wykryto silną korelację pomiędzy wartościami trzech metryk: CBO, RFC, WMC. Dla poszczególnych badanych projektów podawano tam różne wartości, ogólnie jednak współczynniki korelacji pomiędzy tymi metrykami oscylowały w okolicach wartości 0,9. WMC DIT NOC RFC CBO LCOM WMC 1-0,28-0,3 0,63 0,38 0,28 DIT 1-0,22 0,28 0,36 0,32 NOC 1-0,35-0,28-0,48 RFC 1 0,92 0,47 CBO 1 0,39 LCOM 1 Tabela 5: Macierz korelacji - wartości metryk z klas z projektu C Table 5: Correlation matrix values of metrics for project C Macierz korelacji wyliczona na podstawie metryk wyliczonych z wszystkich klas, stworzonych na potrzeby wszystkich czterech projektów daje największy wskaźnik korelacji pomiędzy metrykami WMC i CBO równy 0,6. Stosunkowo wysoki jest również wskaźnik korelacji pomiędzy RFC i CBO (r = 0,45). Zdecydowanie wyższe
wartości współczynnika korelacji pojawią się jednak, gdyby rozpatrywać poszczególne projekty z osobna. Współczynniki korelacji wyliczane dla poszczególnych projektów przyjmują niestety znacznie większe wartości wskazujące, że metryki CBO, RFC oraz WMC są silnie ze sobą skorelowane. Poczynione w rozważanych projektach obserwacje skorelowania metryk dały wyniki pośrednie w stosunku do tych, które uzyskano w [3] i [9]. Warto tu nadmienić, że w [3] współczynniki korelacji były wyliczane na podstawie danych dotyczących wszystkich projektów, a w [9] współczynniki te były wyliczane dla każdego projektu z osobna. Istnieje analogia w badanych tu projektach: współczynniki korelacji wyliczane dla każdego projektu z osobna przyjmują wysokie wartości, natomiast liczone dla wszystkich projektów łącznie, przyjmują stosunkowo niskie wartości. Można więc zaryzykować stwierdzenie, że w obrębie jednego projektu istnieje prosta zależność pomiędzy metrykami CBO, RFC i WMC, jednak dla różnych projektów zależność ta jest inna. Jeżeli jest tak w istocie to oznaczałoby to, że dla każdego projektu z osobna można na podstawie wartości metryk skonstruować model predykcji jakości, jednak bardzo trudno będzie stworzyć model uniwersalny. 4.3 WARTOŚCI METRYK WYLICZANYCH Z DIAGRAMÓW Wartości metryk wyliczanych na podstawie diagramów są przedstawione w podobny sposób jak wartości metryk wyliczanych z kodu źródłowego, z tą tylko Max Min Średnia Mediana δ NATC1 79 0 6,36 3 9,64 NATC2 12 0 1,12 0 1,88 NOPC1 50 0 8,32 5 8,19 NOPC2 43,5 0 6,52 4 6,83 NASC 8 0 0,86 0 1,24 DIT 3 0 0,36 0 0,73 NSUBC 10 0 0,24 0 1,12 Tabela 6: Wartości metryk wyliczanych z diagramów Table 6: Values of diagram metrics różnicą, że nie wprowadzono tutaj podziału na klasy implementacyjne i klasy interfejsu graficznego. Często na diagramach klas nie ma informacji, która umożliwiłaby przeprowadzenie takiego podziału, czasami interfejsu graficznego w ogóle się tam nie modeluje. Metryki związane z dziedziczeniem, czyli NSUBC i DIT, wskazują na znikome wykorzystywanie dziedziczenia. Dodatkowo na niską wartość metryki DIT złożył się fakt, że podczas jej wyliczania nie są uwzględniane, pojawiające się na ścieżce dziedziczenia klasy systemowe. Klasy systemowe również nie były uwzględniane
podczas wyliczania metryki NASC. Klasy te nie są uwzględniane, ponieważ nie pojawiają się na diagramach klas. 4.4 KORELACJA METRYK WYLICZANYCH Z DIAGRAMÓW Współczynniki korelacji dla metryk wyliczanych z diagramów nie przyjmują zbyt dużych wartości. Niechlubnym wyjątkiem jest silne skorelowanie metryk NOPC1 i NOPC2 wynikające z faktu, iż w badanych projektach przeważały metody publiczne. NATC1 NATC2 NOPC1 NOPC2 NASC DIT NSUBC NATC1 1 0,38 0,61 0,39 0,06-0,19-0,05 NATC2 1 0,42 0,49 0,2-0,24-0,06 NOPC1 1 0,87 0,15-0,15 0,13 NOPC2 1 0,14-0,06 0,14 NASC 1 0,05 0 DIT 1 0,04 NSUBC 1 Tabela 7: Macierz korelacji wartości metryk wyliczanych z diagramów Table 7: Correlation matrix values of diagram metrix 5. UZYSKANE REZULTATY Przed konstrukcją właściwego modelu wyliczono współczynniki korelacji pomiędzy wejściami, a wyjściami modelu (tabela 8). Dla metryk wyliczanych z kodu źródłowego przedstawiono trzy wartości. Pierwsza z nich jest wyliczona dla wszystkich klas, druga dla klas implementacyjnych, a trzecia dla klas interfejsu graficznego. Z tab. 8 wynika, że wyjście zależy w jakimś stopniu od wartości metryk WMC, CBO, NOPC, NASC w większości przypadków są one silnie skorelowane z wyjściem. Dokładniejsza analiza sprowadzała się do konstrukcji modeli, które na podstawie wartości metryk podawać będą szacowany czas potrzeby na naprawienie błędów. Badano dwa rodzaje modeli. Pierwszy rodzaj to kombinacja liniowa wejść plus wyraz wolny, drugi natomiast, w stosunku do pierwszego, został wzbogacony o człony interakcyjne, czyli iloczyny dwóch różnych wejść. Do wyliczania współczynników, przez które są mnożone wartości poszczególnych metryk, zastosowano metodę regresji liniowej. 5.1. KONSTRUKCJA MODELU NA PODSTAWIE METRYK KODU ŹRÓDŁOWEGO Podjęto próby konstrukcji oddzielnych modeli dla poszczególnych projektów, dla klas implementacyjnych, dla klas interfejsu graficznego i dla wszystkich przeanalizowanych projektów. W tab. 9 przedstawiono wartości współczynników najbardziej odległe od zera oraz uzyskane korelacje (r) pomiędzy wyjściem z modelu,
a wyjściem zmierzonym. Wartości współczynników są powiązane myślnikiem z określeniem wejścia, któremu są przypisane. Z przedstawionego opisu modeli wynika, że nakład pracy związany z poprawianiem klasy silnie zależy od wartości metryki WMC, prawdopodobnie zależy również od wartości metryki DIT. W modelach z interakcjami często, oprócz tych dwóch metryk, przewijają się metryki LCOM (co jest rezultatem dosyć zaskakującym) oraz CBO (czego z kolei należało oczekiwać). Uzyskane współczynniki korelacji są bardzo wysokie, co świadczy o tym, że modele dobrze oddają szukaną zależność. Z drugiej jednak strony duża różnorodność modeli sugeruje, że mogą one nie być słuszne dla innych, nie badanych tutaj projektów. Projekt A B C D Wszystkie WMC 0,83 0,85 0,85 0,64 0,68 0,1 0,24 0,37 0,75 0,43 0,51 0,04 0,52 0,5 0,66 DIT 0,22-0,2 0,82-0,3-0,3 0,31 0,32 0,08 0 0,26 0,34 0,44 0,03-0,1 0,05 NOC 0,13 0,17 0 0,03 0 0,18-0,1-0,1 0-0,1 0 0 0,13 0,16 0 RFC 0,07 0,04-0,8 0,07 0,05 0 0-0,4 0,4 0,38 0,34-0,5 0,04 0,03 0,07 CBO 0,65 0,65 0,69 0,59 0,61 0,41 0,36 0,38 0,43 0,81 0,85-0,3 0,3 0,29 0,27 LCOM -0,2-0,3 0,91 0,11 0,17 0,23 0,14 0,12 0,33 0,33 0,26-0,3-0,1 0,1 0,12 NATC1 0,28 0,09-0,12 0,14 0,2 NATC2 0,13 0,2-0,21 0,18 0,05 NOPC1 0,23 0,54 0,34 0,34 0,28 NOPC2 0,13 0,5-0,21 0,25 0,2 NASC 0,13 0,27 0,58 0,38 0,02 DIT (diag.) -0,24 0,55-0,1-0,11-0,08 NSUBC -0,1 0-0,1-0,11-0,07 Tabela 8: Współczynniki korelacji pomiędzy wejściami i wyjściem modelu Table 8: Correlations between inputs and outputs of the model Ocena predykcji, czasu potrzebnego na naprawienie błędów w klasie, wygenerowanych przy pomocy modelu z członami interakcyjnymi została przedstawiona na rys. 1. Dla zdecydowanej większości klas model przewidział czas potrzebny do naprawienia błędów w klasie nie różniący się od faktycznie potrzebnego czasu o więcej niż 15 minut. Średni rzeczywisty czas potrzebny na naprawę klasy to 21 minut, a jego odchylenie standardowe wynosi 51 minut.
Modele bez członów interakcyjnych Modele z członami interakcyjnymi Projekt A WMC-0,16; r=0,85 DIT*NOC-0,22;WMC*LCOM-0,1; r=0,97 Projekt B WMC-0,03; CBO-0,03; r=0,76 LCOM-0,1; CBO*LCOM-0,1; r=0,82 Projekt C WMC-0,01; DIT-0,04; r=0,54 LCOM-2,5; DIT*LCOM-0,23; r=0,86 Projekt D WMC-0,03; DIT-0,19; r=0,88 DIT-0,3; WMC-0,2; r=0,99 Wszystkie projekty WMC-0,06; r=0,58 WMC-0,05; CBO-0,04; DIT*LCOM-0,09; DIT*NOC-0,06; r=0,906 Klasy impement. WMC-0,05; NOC-0,06; r=0,58 WMC-0,05; NOC*CBO-0,04; r=0,84 Klasy gui WMC-0,08; r=0,72 WMC-0,2; DIT*CBO-0,02; NOC*CBO- 0,04; r=0,84 Tabela 9: Opis modeli budowanych na podstawie metryk kodu źródłowego Table 9: Description of models which are based on source code's metrics Liczba klas 50 45 40 35 30 25 20 15 10 5 0-80 -70-60 -50-40 -30-20 -10 0 10 20 30 Rysunek 10: Histogram błędów modelu 40 50 60 70 80 9 Figure 1: Histogram with model errors 5.2. KONSTRUKCJA MODELU NA PODSTAWIE METRYK DIAGRAMÓW Modele oparte na metrykach wyliczanych z diagramów są słabej jakości. Wskazują na to niskie wartości współczynników korelacji. Osiągniętych przy ich pomocy wyników nie można więc uznać za wiążące. Z uzyskanych obserwacji wynika, że nakład pracy związany z poprawianiem klasy zależy
najbardziej od liczby metod w klasie (metryki NOPC1 i NOPC2). Słabszą zależnością jest powiązany z liczbą atrybutów (NATC1 i NATC2) i z liczbą asocjacji (NASC). Nie zależy za to prawie wcale od długości ścieżki dziedziczenia (DIT). Modele bez członów interakcyjnych Modele z członami interakcyjnymi Projekt A NOPC2-0,13; r=0,4 NATC2*NOPC1-0,58; NOPC1*NSUBC- 0,85; NASC*NSUBC-1,19; r=0,59 Projekt B NASC-0,08; NOPC1-0,06; r=0,63 NATC2-0,4; NATC1*NASC-0,04; NOPC2*NASC-0,06; r=0,71 Projekt C NOPC1-0,06; r=0,88 NOPC2-0,1; NOPC2*NASC-0,5; NATC2*NOPC1-0,36; r=0,97 Projekt D NATC2-0,19; NOPC1-0,03; r=0,88 NATC1-0,2; NATC2-0,3; NOPC2-0,2; NATC2*NASC-0,07; r=0,99 Wszystkie projekty NOPC1-0,048; r=0,33 NATC2-0,15; NOPC1*DIT-0,19; NASC*NSUBC-0,24; r=0,46 Tabela 110: Opis modeli budowanych na podstawie metryk diagramów Table 10: Description of models which are based on diagram's metrics 6. WNIOSKI I MOŻLIWOŚCI DALSZEGO ROZWOJU Udało się znaleźć zależności pomiędzy wartościami metryk, a jakością aplikacji. W przypadku metryk wyliczanych z kodu źródłowego uzyskano dosyć wiarygodne modele, zdecydowanie gorzej jest jednak z metrykami wyliczanymi z diagramów. Aby otrzymać lepsze rezultaty w przypadku tych drugich warto spróbować wziąć pod uwagę również metryki wyliczane z diagramów sekwencji lub zastosować inny zestaw metryk. Modele konstruowane na podstawie zestawu metryk CK Metrics wykazały, że na czas naprawiania defektów w klasie największy wpływ mają metryki WMC, DIT i CBO. Wyniki takie nie są do końca zgodne z wynikami uzyskanymi w [3]. Tam wykazano dodatnią korelację pomiędzy prawdopodobieństwem wystąpienia błędu w klasie a metrykami DIT, CBO i RFC, oraz ujemną korelację z metryką NOC. Rozbieżności częściowo można wytłumaczyć doborem innego wyjścia modelu. W [3] jest to prawdopodobieństwo wystąpienia błędu w klasie. Takie podejście powoduje, że wszystkie błędy są brane z taką samą wagą. W tej pracy natomiast przypisano błędom wagę równą czasowi potrzebnemu na naprawienie klasy. Ujemna korelacja metryki NOC z awaryjnością klasy wynika z faktu, że klasy o wysokiej wartości tej metryki były w badanych w [3] projektach dokładniej testowane. W badanych tu projektach takich działań nie podejmowano. Nie powinna natomiast dziwić obecność metryki
WMC wśród metryk najmocniej powiązanych z niską jakością klasy. Metryka ta jest bowiem bezpośrednio powiązana z rozmiarem klasy, a im większy rozmiar tym więcej okazji do popełnienia błędu. W przypadku zarówno jednych, jak i drugich metryk, warto oczywiście przeprowadzić dalsze badania weryfikujące uzyskane rezultaty. Opisywany tu eksperyment dotyczył bowiem tylko czterech projektów programistycznych, co nie stanowi niestety reprezentatywnej próbki. Projekty te były bardzo do siebie podobne, zarówno pod względem rozmiaru jak i tematyki, więc uzyskane dla nich wyniki można potraktować jako adekwatne tylko dla projektów takiego właśnie typu. Należy również rozważyć możliwość istnienia słabości uzyskanych modeli, wynikających z zastosowania w projektach różnych języków programowania, co z kolei pociągnęło za sobą konieczność zastosowania różnych narzędzi do wyliczania metryk. Wpływ na wykryte zależności może też mieć stosowana metodyka wytwarzania oprogramowania. W badanych projektach stosowano metodykę bardzo bliską metodyce kaskadowej. Dalsze badań powinny więc przeanalizować możliwość zastosowania uzyskanych wyników dla procesów wytwarzania oprogramowania opartych o metodyki zwinne. LITERATURA [1] Aggarwal K.K., Singhy Y., Kaur A., Malhotra R., Empirical Study of Object Oriented Metrics, Journal of Object Technology, 2006, 5 (8), 150-173. [2] Banasiya J., Davis C.G., A Hierarchical Model for Object Oriented Design Quality Assessment. IEEE Trans. Software Eng, 2002, 28 (1), 4-17. [3] Basili V.R., Briand L.C., Melo W.L., A Validation of Object Oriented Design Metrics as Quality Indicators, IEEE Trans. Software Eng., 1996, 22 (10), 751-761. [4] Bhatti S. N., Why Quality? ISO 9126 Software Quality Metrics (Functionality) Support by UML Suite, ACM SIGSOFT Software Eng. Notes, 2005, 30 (2), 1-5. [5] Bieman J., Kang B.-K., Measuring Design-Level Cohesion, IEEE Trans. Software Eng., 1998, 24 (2), 111-124. [6] Blackburn S.M., Garner R., Hoffmann C., Khang A.M., Mckinley K.S., Bentzur R., Diwan A, Feinberg D., Frampton D., Guyer S.Z., Hirzel M., Hosking A., Jump M., Lee H., Eliot J., Moss B., Phansalkar A., Stefanowić D., Vandrunen T., von Dincklage D., Wiedermann B., The DaCapo benchmarks: java benchmarking development and analysis, 21 st ACM SIGPLAN conference on Object-oriented programming systems, languages, and applications, 2006, 169-190. [7] Blumke I., Zając P., Metryki MOOD w Rational Rose, V Krajowa Konferencja Inżynierii Oprogramowania, 2003, 403-417 [8] Briand L., Daly J., Porter V., Wust J., Predicting Fault-Prone Classes with Design Measures in Object-Oriented Systems, 9 th Int. Symposium on Software Reliability Eng., 1998, 334-343. [9] Chidamber S.R., Darcy D.P., Kemerer C.F., Managerial Use of Metrics for Object Oriented Software: An Exploratory Analysis, IEEE Trans. Software Eng., 1998, 24 (8), 629-639. [10] Chidamber S.R., Kemerer C.F., A Metrics Suite for Object Oriented Design, IEEE Trans. Software Eng., 1996, 20 (6), 476-493.
[11] Etzkorn L., Delugach H., Towards a Semantic Metrics Suite for Object-Oriented Design, 34 th Int. Conference on Technology of Object-Oriented Languages and Systems, 2000, 293-310. [12] Flasiński M., Zarządzanie projektem informatycznym, PWN, Warszawa, 2006. [13] Górski J., Inżynieria oprogramowania w projekcie informatycznym, MIKOM, Warszawa, 1999. [14] Henderson-Sellers B., Object-Oriented Metrics, measures of Complexity, Prentice Hall, 1996. [15] Kan S.H., Metrics and Models in Software Quality Engineering, Addison-Wesley Professional, 2002. [16] Kim H., Boldyref C., Developing Software Metrics Applicable to UML Models, 6 th ECOOP Workshop on Quantitative Approaches in Object-Oriented Software Eng., 2002 [17] Khohgoftaar T.M., Pandy A.S., More H.B., A Neural Network Approach for Predicting Software Development Faults, 3 rd Int. IEEE Symp. Software Reliability Eng., 1992, 83-89. [18] Ohlsson N., Alberg H., Predicting Fault-Prone Software Modules in Telephone Switches, IEEE Trans. Software Eng., 1996, 22 (12), 886-894. [19] Olague H. M., Etzkorn L. H., Empirical Validation of Three Software Metrics Suite to Predict Fault- Proneness of Object-Oriented Classes Developed Using Highly Interative or Agile Software Development Processes, IEEE Trans. Software Eng., 2007, 33 (6), 402-419. [20] Systa T., Yu P., Using OO Metrics and Rigi to evaluate java software, Tampere, University of Tampre, Department of Computer Science, Report A-1999-9, 1999. [21] Stein C., Etzkorn L., Utley D., Computing Software Metrics from Design Documents, 42 nd Southeas regional conference, Huntsville, Alabama, 2004, 146-151. USE OF SOFTWARE METRICS FOR FINDING WEAK POINTS OF OBJECT ORIENTED PROJECTS This paper describes an experiment which was realized in academic environment. This experiment was realized to create a model which will be able to present the relationship between values of software metrics and quality of application. There were studied metrics calculated from source code (LCOM, CBO, RFC, WMC, DIT and NOC) and metrics calculated from UML diagrams (NATC1, NATC2, NOPC1, NOPC2, NASC, DIT and NSUBC). Values of those metrics were used as inputs for the model. Lack of quality was used as output for the model. Lack of quality should be interpreted as time which was spent for fixing bugs in source code. The environment of this experiment consisted of four similar software projects. Each project was developed by programmers with similar experience. Those projects were implemented in object oriented languages: C# and java.