Softwarequalität - Messen von Softwarequalität - PDF

Summary

Dieses Dokument befasst sich mit der Messung von Softwarequalität. Es werden verschiedene Aspekte wie Codekomplexität, Wartbarkeit und Leistung quantitativ bewertet. Es behandelt auch Qualitätsanforderungen und Qualitätsmodelle, die in der Softwareentwicklung verwendet werden.

Full Transcript

Softwarequalität ······························································································ 4 Messen von Softwarequalität Lernziele des Kapitels: Softwaremetriken dienen dazu, Aspekte von Softwareprodukten oder -projekten quantitativ zu bewerten und somit eine objektive Grun...

Softwarequalität ······························································································ 4 Messen von Softwarequalität Lernziele des Kapitels: Softwaremetriken dienen dazu, Aspekte von Softwareprodukten oder -projekten quantitativ zu bewerten und somit eine objektive Grundlage für die Beurteilung von Merkmalen wie Codekomplexität, Wartbarkeit und Leistung zu schaffen. Sie helfen dabei, den Zustand eines Projektes rasch zu erfassen und unterstützen Entscheidungen in der Softwareentwicklung. Das Messen von Softwarequalität zählt somit zu den analytischen Qualitätsmaßnahmen. Nach dem Studium dieses Abschnittes entwickeln die Leserinnen und Leser ein erstes Verständnis für:  Qualitätsmodelle  Die Überführung abstrakter Qualitätsziele durch die Definition konkreter Merkmale und Indikatoren in messbare Größen  Traditionelle Softwaremetriken wie „Lines of Code“ und „zyklomatische Komplexität“, aber auch objektorientierte Metriken  Strukturen und Eigenschaften von Softwaresystemen (Exkurs) Die Aufgabe von Metriken in der Softwarequalität besteht darin, eine objektive, quantifizierbare Grundlage für die Bewertung verschiedener Aspekte eines Soft- wareprodukts oder -projekts zu bieten. Sie ermöglichen es, durch einen schnellen Blick auf relevante Zahlen den aktuellen Zustand eines Projektes zu erfassen und zu beschreiben. Mit Hilfe von Software-Metriken können Teams und Stakeholder die Komplexität des Codes, die Wartbarkeit, die Leistung und andere kritische Quali- tätsattribute effizient messen und überwachen. Dies erleichtert nicht nur die Iden- tifizierung potenzieller Problembereiche und Risiken, sondern unterstützt auch die Entscheidungsfindung und Prioritätensetzung in der Softwareentwicklung und - wartung. Somit zählt das Messen von Softwarequalität zu den analytischen Quali- tätsmaßnahmen. 4.1 Qualitätsanforderungen und Qualitätsmodelle In Abschnitt 1.3.1 haben wir eine Aufzählung von wichtigen Qualitätsaspekten nach Hoffmann (2013) kennengelernt. Derartige Zusammenstellungen gibt es in der ······················································································································ 68 Softwarequalität ······························································································ Literatur viele. Der englischsprachige Wikipedia-Eintrag zu „Qualitätsattributen“ enthält beispielsweise eine umfangreiche, aber nicht umfassende, Liste mit Quali- tätsaspekten: accessibility, accountability, accuracy, adaptability, administrability, afford- ability, agility, auditability, autonomy, availability, compatibility, composa- bility, confidentiality, configurability, correctness, credibility, customizabil- ity, debuggability, degradability, determinability, demonstrability, depend- ability, deployability, discoverability, distributability, durability, effective- ness, efficiency, evolvability, extensibility, failure transparency, fault-toler- ance, fidelity, flexibility, inspectability, installability, integrity, interchange- ability, interoperability, learnability, localizability, maintainability, manage- ability, mobility, modifiability, modularity, observability, operability, or- thogonality, portability, precision, predictability, process capabilities, pro- ducibility, provability, recoverability, redundancy, relevance, reliability, re- peatability, reproducibility, resilience, responsiveness, reusability, robust- ness, safety, scalability, seamlessness, self-sustainability, serviceability, se- curability, simplicity, stability, standards compliance, survivability, sustain- ability, tailorability, testability, timeliness, traceability, transparency, ubiq- uity, understandability, upgradability, usability, vulnerability (Wikipedia Beitragende, 2024b). Ein Klassiker ist der sogenannte „Qualitätenbaum“ von Boehm (siehe Abbildung 9). Durch diesen wird schnell ersichtlich, dass Qualitätsaspekte oftmals in Gruppen an- geordnet sind, beziehungsweise eine Hierarchie bilden. „Zuverlässigkeit“ setzt sich in dieser Abbildung beispielsweise aus „Genauigkeit“, „Konsistenz“ und „Vollstän- digkeit“ zusammen. Für die Eigenschaften auf der untersten und granularen Ebene existiert eine Reihe von Qualitätsmetriken (mit einer beigen Box angedeutet), um deren Erfüllungsgrad zu bestimmen. Mit diesen Metriken werden wir uns in Kürze genauer befassen. Zuvor wollen wir jedoch noch ein wenig mit verschiedenen Be- grifflichkeiten ‚aufräumen‘. ······················································································································ 69 Softwarequalität ······························································································ Abbildung 9: Der „Qualitätenbaum“ von Boehm, i. A. a. Krypczyk & Bochkor (2018, S. 585) Zunächst sollten wir uns bewusst machen, dass die Begriffe „Qualitätsaspekt“, „Qualitätsmerkmal“, „Qualitätseigenschaft“, „Qualitätsattribut“ und „Qualitäts- ziel“ oftmals synonym gebraucht werden und mehr oder weniger das gleiche be- deuten. Dadurch sollte man sich nicht verunsichern lassen. Abbildung 10 hilft dabei, die Zusammenhänge zu veranschaulichen und greift dazu den aus Einheit 1 (Requi- rements Engineering) wohlbekannten Begriff der „Qualitätsanforderung“ auf. Zur Erinnerung: Im ersten Teil der Lehrveranstaltung haben wir die Anforderungen in „Funktionale Anforderungen“, „Qualitätsanforderungen“ sowie „Rahmenbedin- gungen“ unterteilt. Erstere besagen, was das System tun soll (eben welche Funkti- onen es aufweisen soll), letztere Spannen den Rahmen auf, innerhalb dessen dieses Verhalten erreicht werden muss. Die Qualitätsanforderungen hingegen spezifizie- ren, wie sich dieses Verhalten genau darstellen soll. Anteilsmäßig sind Qualitätsan- forderungen den prominenteren Funktionalen Anforderungen überlegen (an diese Art von Anforderungen denken die meisten Entwickler als erstes, wenn sie das Wort „Anforderung“ hören) und auch ihr Einfluss auf das Systemverhalten kann nicht überschätzt werden. ······················································································································ 70 Softwarequalität ······························································································ Abbildung 10: Schematische Darstellung des Zusammenhangs zwischen Qualitätsanforderung, deren Teilaspekte (Qualitätsziele/-aspekte) und Indikatoren (Qualitätsmetrik). Als Beispiel könnte sich die vom Kunden gewünschte Qualitätsanforderung „Hohe Verfügbarkeit des Systems“ aus den Qualitäts- zielen „Robustheit“, „Geschwindigkeit“ und „einfache Benutzeroberfläche“ zusammensetzen, i. A. a. Schneider (2012) Abbildung 10 zeigt, dass eine Qualitätsanforderung aus einem oder mehreren Qua- litätsaspekten bestehen kann. Diese werden als Qualitätsziele bezeichnet, wenn sie konkret angestrebt werden. Um das Erreichen dieser Ziele messbar zu machen, werden Qualitätsmetriken herangezogen. Wie in Teil 1 der Lehrveranstaltung aus- führlich dargelegt, müssen diese Anforderungen und deren Beschreibung bezie- hungsweise Bedeutung zusammen mit dem Kunden herausgearbeitet werden. Kein Weg führt an den Gesprächen und Erhebungen mit den Stakeholdern vorbei. Diese legen die in Abbildung 9 genannten Begriffe oftmals auf ihre eigene Weise aus oder verstehen verschiedene Dinge darunter (anders als zum Beispiel von einer Norm vorgesehen). Gleiches gilt natürlich auch für die in Abbildung 4 gezeigten Qualitäts- merkmale nach Hoffmann (2013). Zudem bedarf es einer Elaboration und Klärung, da selbst die normierten Qualitätsaspekte untereinander verwoben sind, wie in Boehms Qualitätenbaum ersichtlich. Das Ziel aus Sicht der Softwarequalität ist es, sich schrittweise an messbare Indikatoren heranzuarbeiten. Denn sobald diese vor- liegen, kann die Qualität des Produktes, der Projektfortschritt sowie auch die gene- relle Güte der Entwicklungsprozesse innerhalb eines Unternehmens objektiv gemo- nitort werden. Aus den genannten Gründen empfiehlt Schneider (2012) ein sogenanntes „Quali- tätsmodell“ zu erstellen, bei welchem mit Hilfe der Stakeholderinnen vom Abstrak- ten über das Konkrete bis hin zum Messbaren gearbeitet wird (siehe Auflistung ······················································································································ 71 Softwarequalität ······························································································ unten). Dabei können als Anhaltspunkt für den abstrakten Einstieg in der Tat die allgemeinen Qualitätsziele und Qualitätsanforderungen, so wie sie zum Beispiel in Normen festgeschrieben sind, dienen. Konkret formuliert Schneider (2012, S. 33- 34) folgendes Vorgehen, welches er auf drei Stufen beziehungsweise Ebenen auf- teilt: Abstrakte Qualitätsziele: Auf der abstraktesten Stufe werden zunächst die Qualitätsziele definiert, wobei man auf standardisierte Termini aus einer vor- gegebenen Auswahl zurückgreift (z. B. Norm). Hier kann die Kundin in allgemei- nen Begriffen ihre Anforderungen umreißen, indem sie ein Ziel durch andere allgemeine Qualitätsbegriffe präzisiert. Beispielsweise könnte die „Verfügbar- keit des Systems“ durch den Aspekt der „Robustheit“ näher erläutert werden (vgl. Bildunterschrift zu Abbildung 10). In der Regel kann dieser erste Arbeits- schritt bei der Ausformulierung eines Qualitätsmodells zügig erfolgen. Konkrete Qualitätsmerkmale: Der größte Zeitaufwand entfällt auf die mittlere Ebene, bei der es darum geht, die abstrakten Qualitätsziele auf die spezifische Kundensituation und das Projekt anzuwenden. Was bedeutet „Robustheit“ in dem vorliegenden Projektkontext genau? Robustheit gegen Stromausfall, ge- gen Überlastung des Netzes oder Bedienungsfehler? Es ist nicht notwendig, alle Qualitätsmerkmale umfassend zu erläutern, sondern vielmehr sollen sie durch einige wichtige und typische Beispiele verdeutlicht werden. Indikatoren und Metriken: Auf dieser untersten Stufe konzentriert man sich darauf, welche Messgrößen beziehungsweise Indikatoren an welchem Objekt angelegt werden. Dies kann quantitative Messungen oder qualitative Indikato- ren umfassen. Häufig ist es ratsam, diese Ebene nur kurz mit den Entschei- dungsträgern der Kundin zu besprechen und dann eine tiefere Diskussion eher mit dessen technischen Expertinnen zu führen. Nach der Abarbeitung und Ausformulierung der drei genannten Arbeitsschritte liegt als Ergebnis ein maßgeschneidertes Modell vor, welches das individuelle Ver- ständnis der Kundinnen zu ihren Qualitätszielen abbildet. So ist es ausgezeichnet dazu geeignet als Richtlinie für die Entwicklung und als Kriterium zur Bewertung der Software zu dienen. Abbildung 11 zeigt beispielhaft den Ausschnitt aus einem Qualitätsmodell aus dem Lehrbuch von Schneider (2012). Auch hier wird vom Abstrakten, zum Konkreten bis ······················································································································ 72 Softwarequalität ······························································································ hin zu den Indikatoren gearbeitet. Der Einstieg erfolgte über das sehr allgemeine Qualitätsziel „Effizienz“. Auch bei der Unterteilung in „Laufzeiteffizienz“ und „Spei- chereffizienz“ konnten sich Requirements Engineer und Kunde noch an allgemei- nen Begriffen und Richtlinien orientieren. „Bedieneffizienz“ ist hingegen eine ei- gene Namensgebung, um einen Aspekt von Effizienz zu betonen, der dem Kunden bei der Erhebung wichtig war und für welchen kein offizielles ‚Label‘ existiert oder dem Kunden bei der Anforderungsanalyse bekannt war. Es ist legitim und sinnvoll bei dem Erstellen des Qualitätsmodells die Sprache der Auftraggeberinnen zu verwenden. Letztlich war es der Wunsch des Kunden, dass die Gebrauchstauglichkeit des Altsystems derart verbessert werden soll, dass die Anzahl der erfassten Datensätze pro Stunde verdoppelt wird. Dieses konkrete Ziel ist in Abbildung 11 mit einem gestrichelten Kästchen kenntlich gemacht. Weitere konkrete Kundenwünsche zu den anderen Facetten von Effizienz sind ebenfalls ein- gekastelt. Beispielsweise hat sich der Kunde zum Installationsprozess geäußert und konkrete Wünsche zur Geschwindigkeit vorgelegt. Dies führt uns zu den konkreten Indikatoren, die herangezogen werden können, ob die Softwarequalität aus Sicht des Kunden bereits erreicht wurde (in der Abbildung in beigen Boxen dargestellt). In dem vorliegenden Beispiel soll die Installation des zu entwickelnden Produktes weniger als drei Minuten in Anspruch nehmen. Wenn das System erst einmal in- stalliert ist, so soll das Starten durch Doppelklick weniger als 10 Sekunden dauern. Wie detailliert ein solches Qualitätsmodell in der Praxis ausgearbeitet werden kann, hängt von der Erfahrung der Mitarbeiterinnen und von der Verfügbarkeit der Kun- den ab. In den meisten Fällen wird sicherlich kein allumfassendes Modell erstellt werden können. Jedoch ist durch das Abbilden der wichtigsten Qualitätsanforde- rungen samt individueller Indikatoren bereits viel gewonnen, um die Projektabwi- ckelung mit Hilfe von Metriken kontrolliert steuern zu können. ······················································································································ 73 Softwarequalität ······························································································ Abbildung 11: Ausschnitt aus einem Qualitätsmodell, i. A. a. Schneider (2012, S. 36) ······················································································································ 74 Softwarequalität ······························································································ 4.2 Softwaremetriken Durch die Ausbuchstabierung eines Qualitätsmodells werden die Ziele also ‚greif- bar‘. Die Qualitätsanforderung „Effizienz“ ist zu allgemein; man weiß nicht, unter welchen Umständen der Kunde zufrieden sein wird. Durch das ausdifferenzierte Bild des gesamten Qualitätsmodells ergeben sich jedoch für den jeweiligen Kunden spezifische Angriffspunkte. Beispielsweise könnte eine Forderung nach einer hohen „Laufzeiteffizienz“ bei einer Webanwendung für Suchanfragen bestehen. Das ist schon wesentlich spezifischer als die bloße Forderung nach „Effizienz“. Um die Lauf- zeiteffizienz zu messen, könnte man die Zeit erfassen, die benötigt wird, um eine Suche zu starten und die Ergebnisse zu erhalten. Ein spezifisches Vorgehen könnte darin bestehen, die Antwortzeiten der Datenbank zu messen, während unter- schiedlich große Datasets durchsucht werden. Man würde dann vielleicht auf eine Optimierung der Datenbankabfragen, Indizes oder des Cachings abzielen, um die Antwortzeit zu minimieren. Unabhängig vom jeweiligen Optimierungsverfahren, mit der Antwortzeit liegt eine Metrik beziehungsweise ein Indikator vor, um zu eru- ieren, wie nahe man dem Qualitätsziel schon gekommen ist. In der Fachliteratur finden sich viele Metriken zur Bewertung von Software. Eine Softwaremetrik wird im Allgemeinen als eine Funktion definiert, die eine Software- komponente in einen messbaren Wert überführt. Dieser Wert lässt sich als Maß für das Erreichen eines bestimmten Qualitätsziels für die betreffende Softwarekompo- nente interpretieren (gemäß dem IEEE Standard 1061). Nach Schneider (2012, S. 55-56) ist jedoch angebracht, diese Definition zu erwei- tern, sodass Metriken in der Lage sind, alle relevanten Aspekte der Softwareent- wicklung abzudecken. Hierbei sollten neben numerischen Werten auch Zeichen und Symbole als mögliche Ergebnisse einer Metrik in Betracht gezogen werden. Häufig ist es vorteilhaft, dass diese Ergebnisse auch mit einer Maßeinheit versehen werden. Darüber hinaus sind Metriken notwendig, die nicht nur die Software an sich, sondern auch den Prozess ihrer Entwicklung messen, da dieser einen beträcht- lichen Einfluss auf die Produktqualität, also auf die Software, hat. ······················································································································ 75 Softwarequalität ······························································································ Demnach lautet die erweiterte Definition einer Softwaremetrik wie folgt: Definition Softwaremetrik Merksatz Eine Funktion, die entweder eine Softwarekomponente oder ihren Entstehungspro- zess in einen messbaren Wert oder in Zeichen, eventuell mit einer zugehörigen Maßeinheit, überführt, und anzeigt, inwiefern ein entsprechendes Qualitätsziel er- reicht wird. Schneider (2012, S. 55) Zur Integration in eigene Qualitätsmodelle sollte eine Vielzahl an Metriken berück- sichtigt werden, die sich dieser erweiterten Definition zuordnen lassen. Um bei der Auswahl und Anwendung von Metriken den Überblick zu behalten, ist es daher hilf- reich, sie nach verschiedenen Kriterien zu klassifizieren. Metriken können danach eingeteilt werden, welche Aspekte sie vermessen (Schneider, 2012, S. 56): Produktmaße: Diese Kategorie umfasst Kenngrößen, die sich auf Charakteris- tika des Softwareprodukts beziehen und Dimensionen erfassen, die eine solche Eigenschaft quantifizieren. Zum Beispiel könnte es beabsichtigt sein, die Zuver- lässigkeit oder Wartbarkeit oder zunächst den Umfang eines Programms zu be- stimmen. In diesem Kontext kann ein Softwareprodukt auch ein Spezifikations- dokument oder der Entwurf einer Benutzeroberfläche sein, denn Software um- fasst mehr als nur den Code (wie vom ANSI/IEEE Standard 729-1983 festgehal- ten). Prozessmaße: Diese Metriken nehmen den Herstellungsprozess der Software- komponente ins Visier. Die Messung eines Prozesses gestaltet sich schwieriger als die eines Produkts. Die Reifegradmodelle CMMI (vgl. Abschnitt 2.3.1 und 2.3.2) und SPICE (vgl. Abschnitt 2.3.3) weisen einem Prozess eine Bewertungs- zahl zu. Diese reicht bei SPICE von 0 bis 5, wobei die Stufe „SPICE-Level“ ge- nannt wird. Je höher die Zahl, desto ausgereifter ist der Prozess. Die Bewertung des Reifegrades, also die Anwendung der Metrik, erfolgt über mehrere Tage hinweg in sogenannten Assessments. ······················································································································ 76 Softwarequalität ······························································································ Projektmaße: Diese Metriken reflektieren die Entwicklung eines Projekts, ins- besondere im Abgleich mit den Planvorgaben. Kennzahlen zu Aufwand und Kosten, wie die aggregierten Arbeitskosten, sind typische projektspezifische Kenngrößen. Die gesammelten Arbeitsstunden könnten beispielsweise durch eine Stechuhr am Werkszugang erfasst werden. Es ist nicht erforderlich, jede auch nur annähernd brauchbare Metrik zu beherr- schen. Im Berufsalltag genügen oft wenige, gut ausgewählte Metriken sowie die Offenheit, bei Bedarf eigene, neue Metriken zu entwickeln. Es ist essenzieller, das Konzept des zielgerichteten Messens zu verstehen, als zahlreiche spezifische Met- riken auswendig zu lernen. Mit diesem Verständnis kann man flexibel auf unter- schiedliche Ansätze reagieren (Schneider, 2012, S. 56). Daher werden ‚nur‘ drei klassische und weit verbreitete Metriken beispielhaft vor- gestellt: die Länge des Codes („Lines of Code“), die „zyklomatische Komplexität“ von McCabe, ein Maß für die Schwierigkeit von Code, und „Halstead Software Sci- ence“. Letzteres stellt kein einzelnes Maß dar, sondern ein komplettes Set an Met- riken und Formeln für Berechnungen. 4.2.1 Lines of Code (LOC) Metrik Die „Lines of Code“ (LOC) Metrik, manchmal auch als „Source Lines of Code“ (SLOC) bezeichnet, dient zur Messung der Größe eines Softwareprodukts anhand der An- zahl der Zeilen im Quellcode. Diese Metrik umfasst nicht nur den eigentlichen Pro- grammcode, sondern kann auch Kommentare und Leerzeilen einschließen, wenn man die „Total Lines of Code“ (TLOC) zählt. Im Gegensatz dazu fokussiert sich die SLOC-Messung ausschließlich auf die Zeilen mit tatsächlichem Code und schließt Kommentare und Leerzeilen aus. LOC wird häufig für verschiedene Zwecke herangezogen: So lässt sich mit ihrer Hilfe die Größe und Komplexität eines Projekts abschätzen, da eine größere Anzahl von Codezeilen auf ein umfangreicheres und potenziell komplexeres Projekt hinweisen kann. Sie dient ebenso als Maßstab für die Produktivität, indem sie die Menge des geschriebenen Codes im Verhältnis zur aufgewendeten Zeit misst. In der Kosten- schätzung finden LOC Anwendung, um die Kosten für Entwicklung oder Wartung von Softwareprojekten zu prognostizieren. Sie können auch für ······················································································································ 77 Softwarequalität ······························································································ Qualitätsbewertungen herangezogen werden, wobei manchmal angenommen wird, dass weniger Codezeilen auf eine geringere Fehleranfälligkeit hindeuten kön- nen. Jedoch hat die LOC-Metrik ihre Kritikerinnen, die argumentieren, dass sie nicht not- wendigerweise die Qualität oder Funktionalität des Codes reflektiert. Ein effizient geschriebener Code könnte weniger Zeilen aufweisen und dennoch eine höhere Funktionalität bieten als ein weniger effizient geschriebener Code mit mehr Zeilen. Zudem sagt die LOC-Metrik nichts über die Effizienz oder Wartbarkeit des Codes aus und ist anfällig für inflationäre Taktiken, bei denen Entwickler die Zeilenzahl künstlich erhöhen, ohne dass dies einen tatsächlichen Mehrwert für das Projekt bedeutet. Trotz dieser Bedenken bleibt LOC ein gängiges Werkzeug in der Software- entwicklung (Hoffmann, 2013). 4.2.2 Zyklomatische Komplexität Die „zyklomatische Komplexität“ ist eine Softwaremetrik, die von Thomas J. McCabe 1976 eingeführt wurde. Sie misst die Komplexität eines Programms, indem sie die Anzahl der linearen unabhängigen Pfade durch den Quellcode ermittelt. Diese Pfade sind im Grunde die möglichen Wege, die durchlaufen werden können, wenn das Programm ausgeführt wird. Die zyklomatische Komplexität wird oft verwendet, um die Kompliziertheit eines Programms zu verstehen, da sie direkt mit der Anzahl der Entscheidungspunkte wie If-Anweisungen, Schleifen und Fallunterscheidungen (case oder switch Anweisun- gen) zusammenhängt. Eine höhere Anzahl von Entscheidungspunkten bedeutet mehr Pfade und damit eine höhere Komplexität. Abbildung 12 veranschaulicht ver- schiedene Entscheidungspunkte und Programmabläufe als Graphen. Abbildung 12: Verschiedene Abzweigungen, die ein Programm je nach Anweisung nehmen kann, i. A. a. Schneider (2012, S. 63) ······················································································································ 78 Softwarequalität ······························································································ So erfolgt die Berechnung der zyklomatischen Komplexität V(G) eines Programms anhand des Kontrollflussgraphen des Programms, der die Wege abbildet, die zur Laufzeit des Programms durchlaufen werden können. Die Metrik wird mit folgender Formel berechnet: V(G) = E – N + 2P Dabei ist: E die Anzahl der Kanten im Graphen (Übergänge von einem Kontrollpunkt zum nächsten). N die Anzahl der Knoten im Graphen (die Kontrollpunkte selbst, z. B. Anweisun- gen). P die Anzahl der zusammenhängenden Komponenten (im einfachsten Fall 1 für ein unverzweigtes Programm). In der Praxis bedeutet eine höhere zyklomatische Komplexität oft, dass der Code schwieriger zu verstehen, zu testen und zu warten ist. Es wird häufig empfohlen, dass Methoden oder Funktionen mit einer zyklomatischen Komplexität von über 10 überarbeitet werden sollten, um ihre Komplexität zu reduzieren, obwohl dieser Schwellenwert je nach Kontext variieren kann. Abbildung 13 zeigt beispielhaft den Kontrollflussgraphen eines kurzen Auszugs aus einem Programm. Abbildung 13: Auszug aus einem Programm mit dazugehörigem Kontrollflussgraphen, i. A. a. Schneider (2012, S. 64) ······················································································································ 79 Softwarequalität ······························································································ Zusammenfassend ist die zyklomatische Komplexität ein nützliches Maß für die Ver- ständlichkeit und Wartbarkeit von Code, indem sie einen Einblick in die strukturelle Komplexität des Programms gibt (Hoffmann, 2013). 4.2.3 Halstead-Metriken Die Halstead-Metriken sind eine Reihe zusammengehöriger Softwaremetriken, die von Maurice Halstead in den 1970er Jahren entwickelt wurden und die er als „Soft- warewissenschaft“ bezeichnete. Sie stellen den recht weit verbreiteten Versuch dar, die Softwareentwicklung und ihre Komplexität durch quantitative Maße zu charakterisieren. Halsteads Metriken basieren auf tokenisierten Darstellungen 11 von Software und zielen darauf ab, verschiedene Aspekte der Softwarekomplexität zu messen, indem sie die Verwendung und die Verteilung von Operatoren und Ope- randen im Quellcode analysieren. Die grundlegenden Maße, die Halstead vorschlägt, umfassen: n1: Die Anzahl der einzigartigen Operatoren n2: Die Anzahl der einzigartigen Operanden N1: Die Gesamtanzahl der Operatoren N2: Die Gesamtanzahl der Operanden 11 „Tokenisierte Darstellung“ bezieht sich auf den Prozess der Zerlegung von Quellcode in kleinere Teile, die als Tokens bezeichnet werden. Jedes Token ist eine Grundeinheit des Codes, wie ein Schlüsselwort, ein Operator, ein Literal oder ein Bezeichner, die vom Compi- ler oder Interpreter während des Übersetzungsprozesses verwendet werden. Dieser Schritt ist Teil des lexikalischen Analysierens, bei dem der Quelltext in eine Folge von Tokens um- gewandelt wird, die dann für weitere Analysen wie das Parsing oder die Anwendung von Metriken verwendet werden können. In Bezug auf die Halstead-Metriken repräsentieren diese Tokens die Operatoren und Ope- randen im Code. Operatoren sind die Teile des Codes, die Aktionen ausführen, wie z. B. "+" oder "if", während Operanden die Objekte sind, auf die diese Aktionen angewendet wer- den, wie Variablen oder Konstanten. Halsteads Metriken berechnen die Komplexität von Software, indem sie zählen, wie oft verschiedene Operatoren und Operanden im Code vor- kommen und wie diese verwendet werden. ······················································································································ 80 Softwarequalität ······························································································ Aus diesen Grundgrößen leitet Halstead mehrere Metriken ab, darunter: Programmlänge: N = N1 + N2, die Gesamtanzahl der Operatoren und Operan- den Programmvokabular: n = n1 + n2, die Anzahl der einzigartigen Operatoren und Operanden Programmumfang: V = N * log2(n), der geschätzte Umfang des Programms, ba- sierend auf der Länge und dem Vokabular Schwierigkeitsgrad: D = (n1/2) * (N2/n2), der Aufwand, den Code zu verstehen, basierend auf der Anzahl der einzigartigen Operatoren und Operanden sowie der Gesamtanzahl der Operanden Programmieraufwand: E = D * V, das Produkt aus Umfang und Schwierigkeit, gibt den Aufwand an, der zum Schreiben des Codes nötig wäre Zeitaufwand: T = E / 18, wobei die Konstante 18 darauf hinweist, dass 18 Se- kunden benötigt werden, um einen Halstead-Einheitsaufwand zu verrichten Anzahl der ausgelieferten Bugs: B = V / 3000, wobei angenommen wird, dass es einen Bug pro 3000 „Token“ gibt. Diese Metriken sollen Einblicke in die Komplexität, die Lesbarkeit, die Wartbarkeit und andere wichtige Charakteristika der Software geben. Sie können auch verwen- det werden, um den erforderlichen Testaufwand oder die Qualität des Codes zu beurteilen. Es ist wichtig anzumerken, dass Halstead-Metriken zwar nützliche Einblicke liefern können, sie jedoch auch ihre Grenzen haben und nicht alle Aspekte der Software- qualität oder -komplexität abbilden (siehe z. B. nächster Absatz). Sie sollten daher nicht isoliert, sondern als Teil eines umfassenderen Sets von Softwaremetriken be- trachtet werden (Hoffmann, 2013). ······················································································································ 81 Softwarequalität ······························································································ 4.2.4 Objektorientierte Metriken In der Literatur wird hervorgehoben, dass die etablierten Software-Metriken, ein- schließlich der bekannten McCabe- und Halstead-Metriken, primär auf den Prinzi- pien der imperativen Programmierung fußen. Diese Metriken betrachten Pro- gramme als Abfolgen von Befehlen, die sequenziell abgearbeitet werden, und be- rücksichtigen im Wesentlichen die Strukturierung durch Prozeduren und Funktio- nen, ohne allerdings weitere Mechanismen zur Kapselung von Programmsegmen- ten zu berücksichtigen. Diese Orientierung vornehmlich an imperativen Aspekten der Programmierung erscheint zunächst überraschend, kann jedoch durch die his- torische Entwicklung dieser Metriken erklärt werden, da viele davon in einer Zeit entwickelt wurden, in der Konzepte wie Objektorientierung und Vererbung noch nicht etabliert waren (Hoffmann, 2013, S. 263). Es wird jedoch argumentiert, dass die klassischen, auf imperative Programmierung ausgerichteten Metriken grundsätzlich auch auf objektorientierte Sprachen an- wendbar sind. Auch objektorientierte Ansätze folgen in der Implementierung von Klassen- und Objektmethoden dem imperativen Paradigma, wodurch die objektori- entierte Programmierung eher als Erweiterung, denn als fundamentaler Wandel des imperativen Ansatzes angesehen wird. Die Komplexität objektorientierter Pro- gramme lässt sich daher durch klassische Metriken auf Methodenebene erfassen, allerdings mit der Einschränkung, dass diese bestehenden Metriken die Komplexi- tät des gesamten Software-Systems nicht vollständig abbilden können. Als Haupt- gründe dafür werden angeführt, dass rein imperativ ausgerichtete Metriken wich- tige Aspekte objektorientierter Programme, wie die Klassenstruktur und deren Be- ziehungen, nicht erfassen und somit keine umfassende Aussage über die System- komplexität erlauben. Zudem bieten die klassischen Metriken keine Lösungsan- sätze für die Besonderheiten objektorientierter Sprachen, insbesondere im Hinblick auf Vererbung und die Nichtberücksichtigung geerbter Methoden, was die Korrela- tion zwischen Code-Größe und Klassenkomplexität untergräbt (Hoffmann, 2013, S. 263). Um aussagekräftige Ergebnisse zu erhalten ist also eine Erweiterung der prozedura- len Metriken erforderlich, um die spezifischen Merkmale objektorientierter Pro- grammiersprachen zu berücksichtigen (siehe dazu auch den Exkurs zu Softwarest- rukturen in Abschnitt 4.3). In der Vergangenheit wurden zu diesem Zweck ······················································································································ 82 Softwarequalität ······························································································ verschiedene Ansätze vorgeschlagen, die in Komponenten- und Strukturmetriken unterteilt werden können. 4.2.4.1 Komponentenmetriken Hoffmann (2013, S. 264-265) erklärt in seinem Lehrbuch detailliert die Ideen hinter den sogenannten Komponentenmetriken. Mit diesen wird die Bewertung einzelner Bestandteile eines Software-Systems vorgenommen. Diese Elemente werden typi- scherweise als einzelne Klassen betrachtet, in einigen Fällen jedoch auch als ein Verbund von Klassen (wie Pakete oder Bibliotheken). Komponentenmetriken kom- men insbesondere zum Einsatz, um Teilkomponenten vergleichend zu analysieren. Dies ist besonders hilfreich, um zum Beispiel während des Refactorings zu bestim- men, welche Klasse als Nächstes überarbeitet werden sollte. Die gängigen Komponentenmetriken umfassen Maße für den Umfang einer Soft- ware, darunter die Metriken OV („Objektvariablen“), CV („Klassenvariablen“), NOA („Number of Attributes“), WAC („Weighted Attributes per Class“) und WMC („Weighted Methods per Class“), und fallen in die Kategorie der Umfangsmetriken. Diese Kennzahlen eignen sich besonders gut, um Klassen zu identifizieren, die auf- grund ihrer Größe oder der Komplexität ihrer Implementierung hervorstechen. Sie ermöglichen die Erkennung von Komponenten mit großer funktionaler Bedeutung oder solchen, die als monolithische Klassen in kleinere Unterklassen aufgeteilt wer- den könnten. Die Metriken OV, CV und NOA messen die Datenkomplexität anhand der Anzahl der Objekt- und Klassenvariablen. WAC und WMC führen eine zusätzli- che Gewichtung ein, um Attribute und Methoden in ihrer Komplexität zu bewerten. Zu den Vererbungsmetriken – die ebenfalls zu den Komponentenmetriken gezählt werden – gehören die Metriken DOL („Depth of Inheritance“) und NOD („Number of Descendants“), die eine Komponente anhand ihrer Position in der Klassenhierar- chie bewerten. Sie messen die Anzahl der Oberklassen bzw. Unterlassen einer Kom- ponente. Eine gut strukturierte Softwarearchitektur zeichnet sich durch eine aus- gewogene Vererbungshierarchie aus. Lange Vererbungsketten können die Transpa- renz und Wartbarkeit eines Systems negativ beeinflussen. DOL und NOD können als Indikatoren für solche Probleme dienen. Ein weiterer wichtiger Aspekt ist die Anzahl der reimplementierten Methoden, ge- messen durch die Metrik NORM („Number of Redifined Methods“), die ebenfalls zu den Vererbungsmetriken zählt. ······················································································································ 83 Softwarequalität ······························································································ Die Kohäsion, also der Grad der Zusammengehörigkeit von Bestandteilen einer Klasse, eines Pakets oder einer Bibliothek, wird durch die LCOM-Metrik („Lack of Cohesion in Methods“) bewertet. Diese Metrik basiert auf der Differenz zwischen der Anzahl von Methodenpaaren, die gemeinsame Variablen nutzen, und jenen, die unabhängige Variablensets verwenden. Empirische Studien haben die Bedeutung von Vererbungs- und Umfangsmetriken für die Qualitätsbewertung von Klassen unterstrichen. Die bekannte Kohäsions- metrik LCOM wurde jedoch in ihrer Aussagekraft hinterfragt, und es wurden modi- fizierte Kohäsionsmetriken vorgeschlagen, um die Defizite der ursprünglichen Met- rik zu adressieren (Hoffmann, 2013, S. 264-265). 4.2.4.2 Strukturmetriken Im Gegensatz zu Komponentenmetriken, die sich auf die Eigenschaften einzelner Software-Komponenten (wie Klassen oder Module) konzentrieren, richten Struk- turmetriken ihr Augenmerk auf die übergeordnete Architektur und das Zusammen- spiel der verschiedenen Komponenten innerhalb eines Systems. Diese Metriken sind entscheidend für das Verständnis der Komplexität, der Wartbarkeit und der Erweiterbarkeit eines Software-Systems, so Hoffmann (2013, S. 265). Im Bereich der Softwareentwicklung nehmen Kopplungsmetriken eine Schlüsselpo- sition ein, da sie das Zusammenspiel und die Interaktionsmuster zwischen den ein- zelnen Klassen durchleuchten, insbesondere im Kontext von Vererbungsbeziehun- gen. Von besonderer Bedeutung sind dabei die Begriffe Fan-In und Fan-Out: Fan-In einer Klasse C, oft dargestellt als Fin(C), gibt die Anzahl der Klassen an, die auf C zugreifen. Klassen mit hohem Fan-In sind gewöhnlich am unteren Ende der Software-Architektur zu finden, was auf ihre grundlegende Bedeutung hindeutet, während Klassen mit niedrigem Fan-In tendenziell höher in der Ar- chitekturstruktur angesiedelt sind, da sie weniger Abhängigkeiten aufweisen. Im Gegensatz dazu quantifiziert Fan-Out einer Klasse C, kurz Fou(C), die Anzahl der Klassen, auf die C selbst direkt zugreift. Klassen mit hohem Fan-Out befin- den sich üblicherweise am oberen Ende der Software-Architektur, da sie viel- fältige Verbindungen initiieren, während Klassen mit niedrigem Fan-Out am un- teren Ende stehen, was eine geringere Anzahl von Abhängigkeiten impliziert (Hoffmann, 2013, S. 265). ······················································································································ 84 Softwarequalität ······························································································ Zum Abschluss dieses Kapitels seien die Leserinnen und Leser zu einem kurzen Ex- kurs eingeladen, der die oben genannten und vor allem vermessenen Softwarest- rukturen noch einmal explizit und detaillierter beleuchtet. 4.3 Exkurs: Struktur und Eigenschaften von Softwaresystemen Struktur und Architektur eines Softwaresystems bestimmen, wie die verschiedenen Teile des Systems zusammenwirken, um die Gesamtfunktionalität zu gewährleis- ten. Ein gut strukturiertes System ist modulierbar, erweiterbar und wartbar. Somit spielt die Struktur eine relevante Rolle bei der Sicherstellung von Softwarequalität und verschiedene (teilweise oben genannte) Metriken zielen darauf ab, die Qualität dieser Struktur in Zahlen zu fassen. Diese Quantitative Bestimmung soll auf objek- tive Weise ausdrücken, ob es gegebenenfalls Verbesserungspotential bei unserer Architektur geben könnte. Aus diesem Grund folgt ein kurzer Überblick über die Struktur von Softwaresystemen (vgl. z. B. Sommerville, 2016). 4.3.1 Komponenten Eine Komponente in der Softwarearchitektur ist ein selbstständiges Modul, das eine Gruppe von verwandten Funktionen oder Daten kapselt. Jede Komponente hat eine klar definierte Schnittstelle und verborgene Implementierungsdetails. Dies fördert die Wiederverwendung von Code und erleichtert die Wartung, da Änderungen in- nerhalb einer Komponente nicht unmittelbar Auswirkungen auf andere Teile des Systems haben. Eigenschaften von Komponenten: Austauschbarkeit: Komponenten können leicht ausgetauscht werden, wenn sie dieselbe Schnittstelle implementieren. Nicht sichtbarer Zustand: Der interne Zustand der Komponente ist von au- ßen nicht sichtbar oder zugänglich. Wiederverwendbarkeit: Gut definierte Komponenten können in verschie- denen Softwaresystemen verwendet werden. ······················································································································ 85 Softwarequalität ······························································································ 4.3.2 Schnittstellen Die Schnittstelle einer Komponente definiert, wie andere Teile des Systems mit ihr kommunizieren können, ohne ihr inneres Funktionieren zu kennen. Schnittstellen beschreiben die Methoden, die andere Komponenten oder Systemteile aufrufen können, und die Art der Daten, die übermittelt werden können. Eigenschaften von Schnittstellen: Abstraktion: Schnittstellen stellen eine abstrakte Beschreibung der Ser- vices dar, die eine Komponente bietet. Konsistenz: Eine Schnittstelle verändert sich nicht willkürlich, was eine kon- sistente Nutzung durch andere Komponenten ermöglicht. Vertrag: Die Schnittstelle bildet einen Vertrag zwischen der Komponente und der aufrufenden Entität. 4.3.3 Grundlegende Softwarearchitekturen Schichtenarchitektur: Hier wird die Software in hierarchische Schichten un- terteilt, wobei jede Schicht spezifische Dienste für die darüber liegende Schicht anbietet. Die unterste Schicht bietet Dienste für die Hardware, während die obersten Schichten die Benutzerschnittstellen implementie- ren. Serviceorientierte Architektur (SOA): Diese Architektur beruht auf der Idee, dass verschiedene Dienste über ein Netzwerk angeboten und konsu- miert werden können. Sie fördert die Interoperabilität und Flexibilität. Mikroservices: Hier wird die Anwendung als Sammlung kleiner, unabhän- giger Dienste gestaltet, die spezifische Geschäftsziele erfüllen und über wohldefinierte APIs kommunizieren. Ereignisgesteuerte Architektur: In dieser Architektur lösen Ereignisse (Events) die Kommunikation zwischen Komponenten aus, was eine lose Kopplung und hohe Skalierbarkeit ermöglicht. ······················································································································ 86 Softwarequalität ······························································································ 4.3.4 Designprinzipien Um eine solide Softwarearchitektur zu gewährleisten, sollten einige Designprinzi- pien befolgt werden: Hohe Kohäsion und lose Kopplung: Die Funktionalitäten innerhalb einer Komponente sollten eng zusammenhängen, während die Abhängigkeiten zwischen den Komponenten minimal gehalten werden sollten. Offenes/Geschlossenes Prinzip: Komponenten sollten für Erweiterungen offen, aber für Modifikationen geschlossen sein. Prinzip der Trennung von Interessen: Verschiedene Anliegen sollten in se- paraten Komponenten behandelt werden. 4.4 Kontrollfragen Welcher der folgenden Aktivitäten gehört NICHT zum dreistufigen Vorgehen nach Schneider (2012) für die Erstellung eines Qualitätsmodells? Multiple-Choice-Fragen: A) Die abstrakten Qualitätsziele werden zuerst festgelegt, wobei standardisierte Be- griffe genutzt werden. Übung B) Die spezifischen Kundensituationen und Projektkontexte werden zur Anwen- dung der abstrakten Qualitätsziele herangezogen. C) Die konkreten Qualitätsmerkmale werden durch wichtige und typische Beispiele verdeutlicht. D) Die Implementierung von Designprototypen erfolgt als Teil der konkreten Quali- tätsmerkmale. Welche Aussage über Softwaremetriken ist gemäß Schneider (2012) korrekt? Multiple-Choice-Fragen: A) Softwaremetriken können nur numerische Werte als Ergebnisse haben. B) Softwaremetriken sollten nur Produktmaße beinhalten, um relevant zu sein. C) Softwaremetriken können den Softwareentstehungsprozess messen und nutzen Zahlen, Zeichen oder Symbole als Ergebnisse. D) Softwaremetriken bewerten ausschließlich die Qualität des Quellcodes einer Software. ······················································································································ 87 Softwarequalität ······························································································ Was misst die zyklomatische Komplexität nach Thomas J. McCabe? Multiple-Choice-Fragen: A) die Anzahl der Zeilen im Quellcode eines Programms B) die Anzahl der Bugs pro Zeile des Quellcodes C) die Anzahl der Funktionen und Methoden in einem Programm D) die Anzahl der linearen unabhängigen Pfade durch den Quellcode Warum bilden klassische Software-Metriken wie die McCabe- und Halstead-Met- riken die Komplexität objektorientierter Programme nicht vollständig ab? Multiple-Choice-Fragen: A) Sie berücksichtigen nicht die Klassenstruktur und Beziehungen in objektorien- tierten Programmen. B) Sie messen nur die Anzahl der Klassen und Methoden, nicht aber ihre Qualität. C) Sie sind ausschließlich für prozedurale Programmiersprachen anwendbar. D) Sie basieren auf der Anzahl der Codezeilen, was für objektorientierte Programme irrelevant ist. ······················································································································ 88