To measure is to know.
Sir William Thomson, 1824 – 1907, seit 1892 Lord Kelvin of Largs
Wenn wir industrielle Produkte systematisch vergleichen und verbessern wollen, müssen wir die Produkte und deren Herstellungsprozesse präzise beschreiben und bewerten können. Generell ist festzustellen, dass dies bei der Software-Entwicklung im Vergleich zur Herstellung anderer industrieller Produkte viel zu wenig geschieht und dass die Software-Hersteller, aber auch die Kunden zum eigenen Nachteil wenig Interesse daran zeigen. Gründe dafür sind, dass Software als immaterielles Gut nicht fassbar zu sein scheint und dass wir kaum Erfahrung mit quantifizierten Merkmalen haben: Sie sagen uns nichts, so wie uns viele medizinische Laborwerte nichts sagen, wenn wir dazu keine anschauliche Erklärung bekommen.
Während wir beispielsweise ganz selbstverständlich bei der Kaufentscheidung für ein Auto gemessene oder prognostizierte Werte heranziehen (Kraftstoffverbrauch, Größe des Kofferraums, Unterhaltskosten pro Jahr usw.), haben wir für Software solche Werte nicht, und wir rechnen auch nicht damit (!).
Ein Ziel der ingenieurmäßigen Herstellung von Software ist, dass Bewertungen und Messungen in der Software-Entwicklung selbstverständlich werden. Nachfolgend gehen wir auf die Grundlagen des Messens ein, zeigen aber auch, wie schwierig es ist, geeignete Kennzahlen für Software festzulegen.
Da Metriken Modelle sind und Skalen verwenden, ist dieses Kapitel sehr eng mit Kapitel 1, insbesondere mit den Abschnitten 1.8 (Modellierung durch Zahlen: Skalen und Skalentypen) und 1.9 (Übergänge zwischen verschiedenen Skalentypen), verbunden. Wir verzichten darauf, überall die entsprechenden Querverweise einzustreuen.
Im Buch von Fenton und Pfleeger (1997) werden die Grundlagen der Metriken vermittelt. Zur Anwendung, Interpretation und Kritik der Metriken ist das Buch von Kan (2003) eine ergiebige Quelle.
Wenn wir ein Merkmal eines Gegenstands knapp und präzise beschreiben wollen, tun wir das vorzugsweise mit einer Zahl. Die Aussage, dass eine Person 1,87 m groß ist, hat gegenüber allen verbalen Beschreibungen (z. B. »recht groß« oder »nicht so groß wie sein Bruder«) die Vorteile, dass sie kurz, präzise und vergleichbar ist.
Im Software Engineering bezeichnen wir quantifizierte Aussagen über Produkte oder Entwicklungsprozesse als Metriken1. Im IEEE-Glossar ist definiert:
metric — A quantitative measure of the degree to which a system, component, or process possesses a given attribute.
See also: quality metric.
quality metric — (1) A quantitative measure of the degree to which an item possesses a given quality attribute.
(2) A function whose inputs are software data and whose output is a single numerical value that can be interpreted as the degree to which the software possesses a given quality attribute.
IEEE Std 610.12 (1990)
Das Wort Software-Engineering-Metrik oder einfach Metrik bezeichnet also im Sinne der IEEE-Definition für »quality metric« die Abbildung einer Software oder eines Prozesses der Software-Bearbeitung auf eine skalare oder vektorielle Größe. In vielen Fällen ist mit einer Metrik eine bestimmte Vorstellung verbunden, wie die Metrik zu interpretieren ist.
Die wichtigsten Motive und Ziele für den Einsatz von Metriken sind:
Bewerten der Qualität von Produkten und Prozessen
Indem wir messen, können wir zeigen, dass die geforderten (quantifizierten) Qualitäten erreicht wurden. Vor einer Kaufentscheidung können wir die gemessenen Merkmale der in Frage kommenden Produkte vergleichen.
Quantifizieren von Erfahrungen
Nur wenn wir messen, können wir das Erfahrungswissen, das wir in vielen Projekten erworben haben, auch quantitativ belegen.
Vor allem an Kosten-, Termin- und Qualitätsprognosen besteht sehr großer Bedarf.
Unterstützen von Entscheidungen
Nur wenn wir immer wieder Kenndaten erheben, können wir kritische Veränderungen rechtzeitig erkennen und entscheiden, ob ein Reengineering von Komponenten notwendig ist oder eine Neuentwicklung angestoßen werden muss.
Man kann Metriken auch nach ihrem Anwendungsbereich ordnen; die vier wichtigsten sind:
Kostenmetriken liefern Aussagen über Kosten, Personalbedarf und Entwicklungszeit für ein Projekt.
Fehlermetriken liefern Aussagen über die Zahl der entdeckten oder zu erwartenden Fehler.
Volumens- oder Umfangsmetriken geben einen Eindruck von der Größe einer Software-Einheit.
Qualitätsmetriken liefern Aussagen über eine bestimmte Qualität der Software.
Viele Unternehmen haben in der Vergangenheit Projekte durchgeführt, deren Ziel es war, Metriken einzuführen, um diese dann laufend zu erheben. Der Aufwand für solche Metrik-Programme ist erheblich. Natürlich gibt es – wie immer – eine Vielzahl von Publikationen über erfolgreiche Metrik-Programme; Kilpi (2001) berichtet beispielsweise über die Einführung eines Metrik-Programms bei Nokia. Viele Metrik-Programme waren jedoch nicht erfolgreich oder wurden abgebrochen (Dekkers, McQuaid, 2002).
Tom DeMarco, selbst ein Protagonist der Metriken und Metrik-Programme, hat sich in seinem Buch »Why Does Software Cost So Much?« ebenfalls kritisch mit dem Thema Metriken und Metrik-Programme auseinandergesetzt (DeMarco, 1995). Er zeigt Beispiele, wie Metriken und die damit erhobenen Daten fehlinterpretiert wurden und zu falschen Aussagen und Schlüssen geführt haben (darunter auch eine viel zitierte Grafik, aus der geschlossen werden kann, dass etwa 75 % der vom DoD vergebenen Aufträge zu Software führte, die nie eingesetzt werden konnte; tatsächlich waren es aber nur 4 %).
Es gibt also gute Gründe, Metriken einzuführen, und ebenso gute Gründe, dabei behutsam und systematisch vorzugehen und die Ziele nicht zu hoch zu stecken, sondern nur wenige wichtige Metriken konsequent zu erheben und zu verwenden.
Wenn wir Software oder die Software-Entwicklung beurteilen wollen, so geht es letztlich um Fragen der Art:
Wie gut ist die Software X? Ist sie besser als Software Y?
Was wird die Entwicklung der Software Z kosten?
Ist es sinnvoll, das Werkzeug T zur Entwicklung der Software Z einzusetzen?
Wir befinden uns hier in einem nicht vermeidbaren Dilemma: Einerseits wissen wir, dass wir eine sehr komplexe Materie vor uns haben. Jede seriöse Antwort setzt aufwändige Untersuchungen voraus und muss mit vielen Bedingungen und Vorbehalten verbunden werden. Andererseits müssen wir Entscheidungen treffen, also zum Kauf der Software, zur Erteilung oder Annahme des Auftrags, zum Einsatz des Werkzeugs »Ja« oder »Nein« sagen. Das ist eine Metrik des Typs Boolean; einfacher geht es nicht.
Bei der Entwicklung, Auswahl und Anwendung von Metriken geht es immer darum, solche Entscheidungen auf möglichst einfache, billige und nachvollziehbare Art zu unterstützen. Da wir die Beweggründe hinter unseren Entscheidungen nie vollständig formulieren können (und wollen), vollzieht keine Metrik den letzten Schritt und trifft selbst die Entscheidung (was möglich wäre und bei den Metriken im automatisierten Börsenhandel oder in Waffensystemen bereits realisiert ist). Stattdessen liefert sie ein kompaktes Bild, das uns hilft, die Entscheidung zu treffen.
Häufig müssen wir die Daten sammeln, bevor wir wissen, welche Fragen wir damit später klären wollen. In diesen Fällen ist eine Verdichtung der Daten kaum möglich, wir müssen die Rohdaten archivieren. Diese Problematik wird später im Zusammenhang mit der Sammlung von Basisdaten (Abschnitt 14.2.2) und mit GQM (Abschnitt 14.5.1) diskutiert.
Da wir Metriken sowohl auf Software-Komponenten, ganze Software-Systeme und auch auf Software-Projekte und -Prozesse anwenden, sprechen wir allgemein von den Probanden einer Metrik, wenn wir diese Fälle nicht unterscheiden wollen. Den konkreten Wert der Metrik für einen Probanden bezeichnen wir als seine Bewertung.
Eine ideale Metrik liefert uns ein exaktes Bild des Probanden, reduziert auf den Aspekt, den wir betrachten wollen, und genau in dem Maße verdichtet, wie wir es wünschen. Sie sagt uns beispielsweise genau, was die Entwicklung einer Software kosten wird (»Gesamtkosten 2 322 417,11 €«). Möglicherweise ist es uns aber lieber, statt der Gesamtkosten eine Liste einzelner Kostenanteile zu erhalten, weil wir noch erwägen, einen Teil des Systems nicht zu entwickeln, sondern zu kaufen usw. Die ideale Abstraktionsebene gibt es also nicht. Wir wünschen uns aber in jedem Fall, dass die Metriken differenziert, vergleichbar, reproduzierbar, verfügbar, relevant, rentabel und plausibel sind. Die Begriffe bedeuten im Einzelnen:
Die Vielfalt möglicher Bewertungen ist groß genug, um Unterschiede der Probanden, die auf andere Weise erkennbar werden, auch in der Bewertung sichtbar zu machen. Empfindet man z. B. beim Durchlesen zweier Programme das eine als verständlicher, so sollte eine Metrik der Lesbarkeit auch unterschiedliche Werte liefern. Wenn viele oder alle Probanden denselben Wert liefern, ist die Metrik nicht differenziert.
vergleichbar
Die Bewertungen müssen sich vergleichen lassen. Dazu ist mindestens eine Ordinalskala nötig, besser eine Rationalskala, auf der wir Abstände und Verhältnisse bestimmen können. (Die Absolutskala kann wie die Rationalskala behandelt werden.) Die Vergleichbarkeit schließt die Exaktheit ein: Die Bewertung bezeichnet auf der Skala einen bestimmten Punkt, nicht ein Gebiet oder eine »Wolke«. Eine Bewertung sollte also z. B. »3,1« sein, nicht »zwischen 3 und 4« oder »ungefähr 3«; sonst ist sie nicht vergleichbar.
reproduzierbar
Derselbe Proband sollte, wenn er unter gleichen Bedingungen mehrmals bewertet wird, stets die gleiche Bewertung liefern.
verfügbar
Die Bewertungen müssen vorliegen, wenn wir sie brauchen.
relevant
Die Bewertung muss eine praktische Bedeutung, einen Nutzen haben (vgl. das pragmatische Modellmerkmal in Abschnitt 1.2.2). Dieser Nutzen kann aber eventuell erst später sichtbar werden.
rentabel
Die Erhebung der Metrik darf nicht mehr Aufwand erfordern, als nach ihrer Relevanz gerechtfertigt ist. Eine Metrik, die nicht relevant ist, kann also nicht rentabel sein.
plausibel
Wenn die Metrik eine bestimmte Interpretation der Bewertung impliziert (siehe Pseudometriken in Abschnitt 14.4), dann muss diese Interpretation plausibel sein, also mit unserer Beobachtung übereinstimmen. Eine Metrik, die ein schlechtes Programm als gut bewertet oder ein kurzes Dokument als sehr umfangreich, ist nicht zu gebrauchen. Schneidet Programm A bei der Bewertung der Wartungsfreundlichkeit wesentlich besser ab als die Programme B und C, deren Bewertungen sich kaum voneinander unterscheiden, so sollte dies – bei gleichen Bedingungen – auch für die tatsächlich entstehenden Wartungskosten gelten.
Formal bedeutet die Plausibilität eine hohe Korrelation zwischen den Bewertungen und den Beobachtungen.
Tabelle 14–1 erläutert diese Begriffe an positiven und negativen Beispielen.
Merkmal |
positives Beispiel |
negatives Beispiel |
differenziert |
Programmlänge in LOC |
CMM/CMMI für Organisationen, die nicht Stufe 2 erreichen |
vergleichbar |
zyklomatische Komplexität |
Gutachten (Text) |
reproduzierbar |
Speicherbedarf |
Benotung durch Prüfer |
verfügbar |
Zahl der Entwickler |
Zahl der Fehler im Code |
relevant |
zu erwartende Entwicklungskosten |
Metrik Number of Children (NOC) |
rentabel |
Zahl der entdeckten Fehler im Code |
sehr detaillierte Arbeitszeiterfassung |
plausibel |
Kostenschätzung nach COCOMO |
zyklomatische Komplexität eines Programms mit Zeigeroperationen |
Tab. 14–1 Beispiele für die geforderten Eigenschaften von Metriken
Metriken können nach verschiedenen Aspekten klassifiziert werden. Die Norm ISO/IEC 15939 (2007) (Systems and software engineering – Measurement process) unterscheidet zwischen Basismetriken (base metric) und abgeleiteten Metriken (derived metric). Eine Basismetrik bildet ein Attibut ab und kann unabhängig von anderen Metriken erhoben werden. Eine abgeleitete Metrik verknüpft wenigstens zwei Basismetriken, um ein Attribut zu bewerten, das nicht direkt gemessen werden kann.
Wir unterscheiden Metriken nach dem eingesetzten Messverfahren. Die (aktuelle) Körpergröße eines Menschen können wir durch eine Messung leicht feststellen. Andere Merkmale wie die Sprachkompetenz sind nicht messbar, weil uns die Messvorschrift fehlt. So können wir die Sprachkompetenz durch eine Prüfung beurteilen, aber nicht messen. Ebenso wenig lässt sich die Lebenserwartung eines Menschen messen. Hier brauchen wir eine Prognose; wir müssen die gesuchte Größe aus geeigneten Indikatoren ableiten, hochrechnen, synthetisieren.
Auch im Software Engineering setzen wir alle drei Verfahren ein, um Software, Software-Projekte oder Software-Prozesse zu beschreiben. Wir unterscheiden darum zwischen objektiven und subjektiven Metriken sowie Pseudometriken (Tab. 14–2).
objektive Metrik |
subjektive Metrik |
Pseudometrik |
|
Verfahren |
Messung, Zählung, evtl. auch Normierung |
Beurteilung durch Gutachter, verbal oder auf vorgegebener Skala |
Berechnung (auf der Basis von Messungen und/oder Beurteilungen) |
Vorteile |
exakt, reproduzierbar, kann automatisch erhoben werden |
nicht unterlaufbar, plausible Resultate, auch für komplexe Merkmale geeignet |
liefert relevante, unmittelbar verwertbare Aussage über nicht sichtbares Merkmal |
Nachteile |
nicht sicher relevant, meist unterlaufbar, keine Interpretation |
Erhebung aufwändig, Qualität der Resultate hängt stark von den Gutachtern ab |
schwer nachvollziehbar, pseudoobjektiv |
Beispiele allgemein |
Körpergröße |
Gesundheitszustand |
Body Mass Index (BMI) |
Beispiele im Software Engineering |
Größe, angegeben in LOC oder NCSI; Zahl der Fehler |
Benutzungsfreundlichkeit; Schwere eines Fehlers |
Produktivität; Kostenschätzung nach COCOMO |
Meistens angewendet für |
Sammlung einfacher Basismetriken |
Qualitätsbewertung, Fehlergewichtung |
Prognosen (Kostenschätzung), Bewertungen |
In den folgenden Abschnitten 14.2, 14.3 und 14.4 behandeln wir diese drei Arten und diskutieren die jeweiligen Probleme.
In der Umgangssprache verbinden wir mit dem Begriff der Messung meist die Vorstellung, dass die Ergebnisse auf einer Rationalskala liegen. (Die Skalentypen waren in Abschnitt 1.8.1, S. 19, eingeführt worden.) Das trifft für Längen, Gewichte und Stromstärken gleichermaßen zu. Im Software Engineering messen wir in diesem Sinne kaum; nur die Zeit wird (z. B. als Entwicklungsdauer oder Antwortzeit) wirklich gemessen. Fast alle anderen Größen werden durch Zählung erfasst, sie liegen auf einer Absolutskala. Das gilt für die Anzahl der Code-Zeilen, für die Zahl der Fehler, für die Länge der Parameterlisten usw. Wenn wir von Messung sprechen, ist also die Zählung eingeschlossen. Wie in Abschnitt 1.8.1 beschrieben ist, behandeln wir die Resultate der Zählung oft als rationale Zahlen.
Da viele Informationen, die für die Software und für die Software-Projekte von Bedeutung sind, in digitaler Form vorliegen, ist es relativ einfach, sie zu erheben; wir müssen sie nur einsammeln. Das gilt vor allem für Kennzahlen wie die Programmlänge oder die Anzahl der gefundenen Fehler. Trotzdem ist die Sammlung solcher Daten weder trivial noch billig: Wir brauchen sinnvolle, standardisierte Definitionen und Verfahren, um sicherzustellen, dass wir nicht Daten anhäufen, die unterschiedliche Voraussetzungen haben und darum nicht vergleichbar sind.
In der Praxis werden mehr Metriken verwendet, als die Praktiker selbst bemerken; solche Angaben sind selbstverständlich und werden nicht als Metriken aufgefasst. Man vergleiche dazu die Liste der top ten industrial software metrics von B.W. Boehm (1987):
1. Finding and fixing a software problem after delivery is 100 times more expensive than finding and fixing it during the requirements and early design phases.
2. You can compress a software development schedule up to 25 percent of nominal, but no more.
3. For every dollar you spend on software development you will spend two dollars on software maintenance.
4. Software development and maintenance costs are primarily a function of the number of source instructions in the product.
5. Variations between people account for the biggest differences in software productivity.
6. The overall ratio of computer software to hardware costs has gone from 15:85 in 1955 to 85:15 in 1985, and it is still growing. (Wie wir heute wissen, ist diese Aussage falsch. Die Leistungserhöhung der Hardware führt nicht zur Kostenumverteilung, sondern zur Substitution, siehe dazu Abschnitt 3.1.1.)
7. Only about 15 percent of software development effort is devoted to programming. (Vgl. die Zahlenangaben in Abschnitt 4.2.)
8. Software systems and software products each typically cost three times as much per instruction for fully developed software as does an individual software program. Software-system products cost nine times as much.
9. Walkthroughs catch 60 percent of the errors.
10. Many software phenomena follow a Pareto distribution: 80 percent of the contributions comes from 20 percent of the contributors. (Wir sehen das Verhältnis 20 zu 80 beispielsweise bei den Paaren modules/cost, modules/errors, errors/cost to fix, modules/execution time, tools/tool usage.)
Diese Liste enthält tatsächlich keine Metriken, sondern Aussagen, die aus deren Anwendung folgen. Die wichtigsten Metriken sind daraus aber leicht abzulesen:
a) Umfang der Programme, angegeben in DLOC (delivered lines of code)
b) Erstellungsaufwand, in Personentagen, -stunden oder -wochen
c) Kosten (in einer Währung)
d) Fehlerzahl, Angaben absolut oder in Fehler pro tausend DLOC
Schon diese – scheinbar trivialen – Metriken machen erhebliche Probleme, denn der Teufel sitzt im Detail: Eine präzise Definition der Code-Zeile, die sich mit allen eingesetzten Programmiersprachen verträgt und international anwendbar ist, macht beträchtliche Schwierigkeiten (siehe Park, 1992). Das Buch von Grady und Caswell (1987) zeigt, welche Anstrengungen ein Konzern unternehmen muss, um nur bei den Metriken a und b Fortschritte zu erzielen.
Dass die Messungen sinnvoll sind (oder wären), zeigt sich immer dann, wenn über Verbesserungen des Software Engineerings gesprochen wird. In aller Regel stellt sich heraus, dass einfache Fragen nicht geklärt werden können, weil die Daten nicht erhoben und archiviert wurden. Selbst die Kosten eines abgeschlossenen Projekts sind oft nicht verfügbar, oder sie sind zwar verfügbar, werden aber mit Kommentaren versehen wie »Das waren natürlich nicht die wirklichen Kosten«. Nur in ganz wenigen Organisationen gibt es präzise Aufzeichnungen über Fehlerzahlen, Fehlerkosten und die Kosten der Software-Wartung. Ohne solche Daten sind aber Entscheidungen über Investitionen in besseres Software Engineering sehr riskant und werden kaum getroffen.
Wenn ein Patient im Krankenhaus plötzlich überraschende Symptome zeigt und in einen kritischen Zustand gerät, schaut der Arzt nach, ob die Daten, die über den Patienten gesammelt wurden, Hinweise auf die Gründe geben und damit einen Fingerzeig auf die gebotene Therapie. Die regelmäßige Erhebung dieser Daten (Körpertemperatur, Blutdruck, bestimmte Laborwerte) muss vorsorglich stattfinden, ohne speziellen Anlass; wenn sie benötigt werden, ist es zu spät, sie zu erheben. Das gilt analog in einem Software-Projekt.
Aus diesem Grunde sollte man zur Erhebung objektiver Metriken Basisdaten definieren und Analysewerkzeuge bereitstellen, die die Basisdaten erheben und archivieren. Da es sich ganz überwiegend um Code-Metriken handelt, müssen die spezifischen Eigenschaften der Programmiersprachen berücksichtigt werden. Man sollte sich aber nicht auf Code-Metriken beschränken, nur weil sie so einfach zu messen sind. Informationen über die anderen Dokumente und über den Projektverlauf sind ebenfalls sehr nützlich.
Jede Verwendung einer Metrik erfordert einen Vergleich: Wenn ich wissen will, ob die Zahl der Fehler in den letzten Monaten gestiegen ist, muss ich wissen, wie hoch sie vorher war; wenn jemand vermutet, dass der Aufwand für Reviews zu groß ist, müssen die Aufwandszahlen anderer oder früherer Projekte bekannt sein. Allgemein können wir zwischen einem Längsvergleich jüngerer mit älteren Daten und einem Quervergleich der Daten aus mehreren Bereichen unterscheiden. Der Quervergleich hat den Vorteil, dass er nicht erst nach längerer Datensammlung möglich ist. Praktisch ist er aber kaum durchführbar, weil er voraussetzt, dass die Vergleichsdaten unter gleichen Bedingungen nach gleichen Vorschriften erhoben werden. Das ist nur möglich, wenn die Prozesse sehr ähnlich sind. Aus diesem Grunde gibt es auch kaum Literatur, die brauchbare Vergleichsdaten zur Verfügung stellt; das nicht mehr ganz neue Buch von Capers Jones (1996) ist eine bekannte Ausnahme, die freilich auch die Grenzen des Quervergleichs zeigt. Der Längsvergleich ist dagegen eine sichere Strategie, vorausgesetzt, die Prozesse und die Metriken bleiben stabil.
Jede praktische Arbeit beginnt mit der Definition der Metriken. Auf den ersten Blick erscheint das sehr einfach. Man unterschätze dieses Problem nicht! In jeder Definition gibt es Fußangeln. Die folgenden Beispiele zeigen keine »endgültigen« Definitionen, sondern nur Ansätze, die in der Praxis als Vorlage dienen können.
Dimension |
Bezeichnung |
Einheit |
Messvorschrift |
Größe einer Gruppe, Abteilung usw. |
Kopfzahl |
– |
Anzahl der besetzten Stellen, gerundet auf Zehntel; in der Rechnung werden Teilzeitstellen auf Promille gerundet |
Programmumfang |
– |
LOCtot |
Anzahl der Zeilen insgesamt |
Netto-Programmumfang |
– |
LOCne |
Anzahl der nicht leeren Zeilen |
Codeumfang |
– |
LOCpars |
Anzahl der Zeilen, die nicht (nur) nichtdruckbare Zeichen und Kommentare enthalten |
Ausgelieferter Progammumfang |
– |
DLOCtot |
wie LOC, aber nur der Code, der (als Quelle oder nach Übersetzung) an den Kunden geht |
Anzahl der Einheiten |
Unit-Count |
– |
Anzahl der Einheiten, wie sie für die Konfigurationsverwaltung definiert sind |
Tab. 14–3 Beispiele für die Definition einfacher Metriken
Eine wichtige Frage ist, wer die Metriken wann erhebt. Die Entwickler können viele Metriken ohne Mühe ermitteln und notieren; praktisch funktioniert das aber sehr oft nicht, weil der Zeitpunkt unklar ist: Nach einer Messung wird weiter am Dokument gearbeitet, die Versionsnummer oder das Datum zum Prüfling stimmen nicht, sodass später nicht klar ist, um welchen Prüfling es sich gehandelt hat. Darum ist es sehr viel sinnvoller, wenn die Messungen zu einem definierten Zeitpunkt erfolgen, nämlich bei Übergabe einer Software-Einheit an die Konfigurationsverwaltung (Abschnitt 21.4). Dort liegt auch die Verantwortung für die Erfassung der Daten.
Aufwandsdaten müssen regelmäßig aus der Zeitaufschreibung übernommen werden. Fehlerdaten sollten im Zuge der Prüfungen sofort erfasst werden (in den Reviews und Testauswertungen). Fehler, für die es eine Problemmeldung gibt (siehe Abschnitt 22.2.2), werden von der Konfigurationsverwaltung registriert.
Zwischen den Basisdaten bestehen einfache Zusammenhänge: Eine Arbeitsstunde kostet etwa 100 €, ein Projekt, das n Stunden Aufwand gebraucht hat, liefert ein System mit etwa 2n LOC. (Achtung, hier ist der Gesamtaufwand im Projekt gemeint, nicht der Codieraufwand!) Pro Code-Zeile kostet eine Software damit etwa 50 €. Tausend Zeilen Code enthalten etwa fünf Fehler (bei den besseren Projekten vor dem Test, bei den schlechteren nach dem Test).
Das sind nur ganz grobe Anhaltspunkte, und viele Projekte weichen davon erheblich nach oben oder unten ab. Die Faustformeln sind aber nützlich, wenn man einzelne Zahlen hört und daraus eine Vorstellung vom Projekt ableiten möchte. Wenn drei Leute ein Jahr lang gearbeitet haben, kann man das in etwa 6000 Arbeitsstunden übersetzen. 12000 LOC ist also ein Schätzwert für die Größe des entwickelten Systems. Wenn im Test 80 Fehler gefunden wurden (d. h. etwa 13 Fehler auf tausend Zeilen), waren die Leute entweder sehr viel produktiver als hier angenommen oder haben keine gute Qualität geliefert.
Man sollte bei diesen Formeln aber nicht den Hinweis von Boehm vergessen (Abschnitt 14.2.1, Punkt 8): Ein Programm, das unverbunden in der Landschaft steht, das nicht verkauft werden muss und nicht als Produkt an vielen Stellen im Einsatz ist, braucht sehr viel weniger Aufwand. Darum entsteht in studentischen Projekten meist viel mehr Code, als die Faustformeln erwarten lassen.
Was sich überhaupt sagen lässt, lässt sich klar sagen; und wovon man nicht reden kann, darüber muss man schweigen.
Ludwig Wittgenstein, Tractatus Logico-Philosophicus, 1921
Ludwig Wittgensteins tertium non datur2 gilt in den exakten Wissenschaften bis heute als Dogma. Wo aber die volle Exaktheit nicht erreichbar ist, führt es in die Wittgenstein-Falle, weil es unsere vielen Möglichkeiten auf eine simple Alternative zwischen klar sprechen und schweigen reduziert. Tatsächlich gibt es ja viele Aussagen, die vage oder schwammig, aber dennoch nützlich sind. In diesen Fällen muss die Beurteilung an die Stelle der Messung treten.
Explizite Beurteilungen gibt es, seit sich Menschen um ein Amt bewerben oder Handlungen von Gerichten bewertet werden. Dabei wird in der Regel keine Metrik im engeren Sinne verwendet, sondern ein Text verfasst, der das Urteil ausdrückt. Eine Mischung von Beurteilung und Messung ist die Benotung: Obwohl es sich um eine subjektive Einschätzung handelt, ist das Resultat eine Zahl. Bei näherer Betrachtung zeigt sich allerdings, dass wir damit nur auf einer Ordinalskala liegen. Denn die Note 5 (im deutschen Schulsystem) ist schlechter als die Note 4; niemand kann aber behaupten, dass der Unterschied zwischen 3 und 4 der gleiche ist wie zwischen 4 und 5. Wenn in der Schule die Noten der Klassenarbeiten am Jahresende durch das arithmetische Mittel zu einer Zeugnisnote verdichtet werden, ist das inkorrekt, denn die Bildung eines Mittelwerts setzt eine Intervallskala voraus. Zulässig (und vermutlich auch sinnvoller) wäre die Bildung des Medians.
Während praktisch alle objektiven Metriken (Messungen) Werte liefern, die differenziert, vergleichbar und reproduzierbar sind, haben die subjektiven Metriken (Beurteilungen) ihre Stärken bei der Relevanz und der Plausibilität. Verfügbarkeit ist meistens gegeben, es sei denn, die Zeit ist zu knapp. Die Rentabilität ist kritisch, weil eine Beurteilung unvermeidlich Zeit und damit Geld kostet.
Die Präzision von Beurteilungen kann wesentlich verbessert werden, indem man die Aussagen gewissen Regeln unterwirft und die zulässigen Bewertungen oder Noten möglichst genau definiert. Genau dieses Verfahren setzt Boehm (1981) erfolgreich ein, wenn er für die verschiedenen Projekttypen und Korrekturfaktoren für COCOMO genaue Charakteristika angibt.
Tabelle 14–4 zeigt drei Gruppen von Beurteilungen und Möglichkeiten, die Reproduzierbarkeit und Vergleichbarkeit der Resultate positiv zu beeinflussen.
Art der Bewertung |
Beispiel |
Probleme |
Möglichkeiten zur Verbesserung |
Feststellung |
»Die Spezifikation liegt vor.« |
Die Begriffe sind unklar, es sind kaum Folgerungen möglich. |
Nur bestimmte Feststellungen zulassen und diese genau charakterisieren. |
Bewertung |
»Das Modul ist raffiniert codiert.« |
Bietet keine Grundlage für einen Vergleich. |
Nur bestimmte Aussagen anbieten und diese auf einer Skala anordnen, sodass ein Vergleich möglich ist. |
Benotung |
»Die Lesbarkeit erhält die Note 4.« |
Die Beurteilung ist subjektiv, die Benotung nicht reproduzierbar. |
Kriterien für jede Notenstufe definieren, Beispiele anbieten, die zeigen, wie benotet werden soll. |
Tab. 14–4 Vergleich einiger Bewertungsarten
Die Einsicht, dass sich manche Qualitätsmerkmale vermutlich auch in Zukunft nicht messen lassen (»transzendente Qualitäten« nach Kaposi, Kitchenham, 1987), braucht uns nicht von allen Versuchen abzubringen, Wertungen zu quantifizieren.
Das nachfolgende Beispiel ist – übersetzt und vereinfacht – einem Vortrag von Motoei Azuma, Waseda-Universität in Tokio, entnommen. Die Technik wurde auch publiziert (Sunazuka, Azuma, Yamagishi, 1985). Sie wurde bei NEC (Nippon Electric Company) eingesetzt, um die Qualität der Software systematisch zu beurteilen. Erfolgreiche Entwickler wurden durch Prämien belohnt.
Bevor die angestrebten Qualitäten bewertet werden können, müssen sie definiert und durch verschiedene Kriterien beschrieben sein. Abbildung 14–1 zeigt exemplarisch die Beschreibung des Qualitätsaspekts »Fehlerbehandlung« als Teil des Qualitätskriteriums »Konsistenz« und die Vorgehensweise für die Beurteilung.
DC040 |
Regeln zur Fehlerbehandlung |
Konsistenz |
Definition |
Ist die Fehlerbehandlung definiert und eingehalten? |
|
Erklärung |
Die Fehlerbehandlungsstrategie soll vor dem Entwurf festgelegt und dann konsequent verfolgt werden, damit es im Betrieb nicht zu inkonsistenten oder unverständlichen Reaktionen des Systems kommt. |
|
Einheit |
Modul |
|
Vorgehen |
1. Namen aller Module auf Formblatt notieren |
|
Bemerkung |
|
Abb. 14–1 Definition eines Qualitätsaspekts und seiner Bewertung
Wie man im Formular (siehe Abb. 14–2) sieht, werden die Bewertungen der einzelnen Module summiert und auf den Bereich 0 bis 1 normiert. Bei einfacheren Varianten, in denen statt einer Note nur JA oder NEIN als Antwort zugelassen ist, ergibt der Anteil der positiven Antworten das Gesamtresultat.
Die Resultate für die einzelnen Kriterien werden dann, unter Berücksichtigung von Gewichtungen, zu komplexeren Qualitätswerten zusammengefügt. Diese können durch ein Balken- oder Kiviat-Diagramm3 (siehe Abb. 14–3) visualisiert werden. Wenn man regelmäßig die gleiche Darstellung verwendet, kann man auf einen Blick das Qualitätsprofil eines Systems erkennen und einschätzen.
Abb. 14–2 Bewertungsformular nach Azuma (kursiv: Einträge des Gutachters)
Die Qualität Wartbarkeit könnte beispielsweise anhand der Kriterien Normenkonformität, Lesbarkeit, Typkontrolle, Lokalität und Testbarkeit bewertet werden. Diese Kriterien müssen weiter differenziert werden, damit die wichtigsten Qualitätsaspekte berücksichtigt und angemessen gewichtet werden (siehe Tab. 14–5).
Normenkonformität |
Lokalität |
- Größe der Einheiten (Module etc.) - Kennzeichnung - Bezeichnerwahl - Gestaltung (Layout) - Separierung der Literale - Kommentierung |
- Parameterverwendung - Information Hiding - Ablauflokalität - Gestaltung der Außenschnittstelle(n) |
Lesbarkeit |
Testbarkeit |
- Datentypen - Ablaufstrukturen - Kommentierung |
- Testrahmen - Testdaten - Vorbereitung zur Testauswertung - Diagnose-Komponenten - Dynamische Konsistenzprüfungen |
Typkontrolle |
|
- Typdifferenzierung - Typbeschränkung |
Tab. 14–5 Tabelle der zu bewertenden Qualitätskriterien und Aspekte
Für alle Aspekte ist eine Skala anzugeben, beispielsweise 0 (extrem schlecht) bis 10 (extrem gut).
Die Bewertungen der einzelnen Kriterien ergeben sich dann als Mittel der Aspektbewertungen, die Gesamtbewertung ist das Mittel dieser Teilbewertungen. (Die Problematik einer solchen Rechnung wurde bereits im Abschnitt 1.9.4 diskutiert.) Natürlich können durch Gewichtungen Prioritäten gesetzt werden, die Mittelung muss dann diese Prioritäten berücksichtigen.
Seien m Einzelnoten ni im Bereich 1 bis N vergeben worden, so ergibt sich das Mittel q als
Werden zusätzlich Gewichtungen berücksichtigt, so tritt an die Stelle von m die Summe der Gewichte M:
Tabelle 14–6 zeigt dieses Bewertungsverfahren am Beispiel der beiden ersten Kriterien für die Qualität Wartbarkeit.
Normenkonformität (Gewicht 5) |
Gewicht gi |
Bewertung ni |
gi · ni |
Größe der Einheiten (Module etc.) |
2 |
10 |
20 |
Kennzeichnung |
1 |
8 |
8 |
Bezeichnerwahl |
4 |
5 |
20 |
Gestaltung (Layout) |
2 |
8 |
16 |
Separierung der Literale |
1 |
0 |
0 |
Kommentierung |
4 |
3 |
12 |
Summen normalisiert |
14 |
5,42 |
76 |
Lesbarkeit (Gewicht 3) |
Gewicht gi |
Bewertung ni |
gi · ni |
Datentypen |
1 |
8 |
8 |
Ablaufstrukturen |
1 |
10 |
10 |
Kommentierung |
1 |
2 |
2 |
Summen normalisiert |
3 |
6,67 |
20 |
Tab. 14–6 Beispiel für die Auswertung einer Qualitätsbeurteilung
Die Ergebnisse der Bewertungen werden nach folgender Formel normalisiert:
Für die Gesamtbewertung Q folgt (nur aus diesen beiden Kriterien) ein Wert von
Q = ((5,42 · 5) + (6,67 · 3))/(5 + 3) = (27,1 + 20) / 8 = 47,1 / 8 = 5,89
Die hier gezeigte Qualitätsbewertung beruht darauf, dass Gutachter die Prüflinge untersuchen und anhand vorgegebener Maßstäbe Punkte vergeben. So erhält man zunächst eine Menge von Einzelbewertungen, die anschließend zusammengefasst werden.
Erste Voraussetzung für den Einsatz dieses Verfahrens sind Kriterien, wohldefiniert und gewichtet. Je klarer die Definitionen sind, umso kleiner wird die Streuung bei der Bewertung durch verschiedene Gutachter sein. Aber erst die Routine, also die wiederholte Anwendung der Kriterien und die Diskussion der Ergebnisse, schafft für alle Beteiligten Sicherheit und Vertrauen.
Die Kriterien und Gewichte müssen projektabhängig bestimmt werden. Dabei sollten allerdings die Kriterien selbst unverändert bleiben: Es geht also nur darum, das Gewicht festzusetzen, eventuell auch auf null, falls das Kriterium keine Rolle spielt.
Die Kriterien sollten untereinander möglichst unabhängig sein, sich also so wenig wie möglich gegenseitig beeinflussen. Die Literatur über Software-Qualitätssicherung, insbesondere der Bericht von McCall und Matsumoto (1980), enthält Hinweise auf geeignete Kriterien.
Das beschriebene Bewertungsverfahren lässt sich einführen, wenn folgende Bedingungen erfüllt sind:
Die Ziele und ihre Prioritäten stehen fest und sind bekannt.
Die Konsequenzen der Bewertung sind klar und bekannt.
Allgemein akzeptierte Gutachter sind bestimmt.
Die Gutachter haben an Spielmaterial geübt.
Die Resultate der ersten Versuche werden nicht zu hoch bewertet, das Verfahren wird verbessert, bevor die Beurteilungen Wirkungen zeigen.
Erfahrene Entwickler wirken auch selbst als Gutachter.
Kriterienkataloge und Gewichte werden regelmäßig überprüft.
Die naheliegende Kritik an diesem Verfahren betrifft die Subjektivität der Bewertung: Dagegen hilft nur die Erfahrung. Es ist wichtig, die Resultate der ersten Versuche nicht zu hoch zu bewerten und das Verfahren zu verbessern, bevor die Entwickler mit handfesten Konsequenzen konfrontiert werden. Das Problem wird wie bei anderen Bewertungsverfahren (Reviews) entschärft, wenn die Spielregeln allen Beteiligten klar sind und eine koordinierende Stelle, die Software-Qualitätssicherung, Missbrauch verhindert.
Als Pseudometriken werden alle Metriken klassifiziert, die aus gemessenen oder geschätzten Werten berechnet werden, weil man sie nicht direkt messen kann. Die Metrik zeigt – das ist der Anspruch ihrer Urheber – eine relevante Eigenschaft der Software oder des Prozesses an. Praktisch handelt es sich entweder um Qualitätseigenschaften, denn diese lassen sich nicht direkt an der Software ablesen, oder um Prognosen, beispielsweise die zu erwartenden Entwicklungskosten oder die Zahl der Fehler, die voraussichtlich in den nächsten n Jahren entdeckt werden.
Die Relevanz ist damit für Pseudometriken in der Regel gegeben; sie sind ja dafür konstruiert. Dafür ist die Plausibilität grundsätzlich zu bezweifeln. Wir müssen also bei einer Pseudometrik zeigen, dass sie tatsächlich die relevante Eigenschaft widerspiegelt.
In jedem Fall besteht die Anwendung einer solchen Metrik aus drei Schritten:
1. Die Eingabegrößen der Metrik werden durch Zählung, Messung oder Schätzung bestimmt.
2. Entsprechend dem Modell, das der Metrik zu Grunde liegt, wird die Metrik berechnet.
3. Das Resultat wird so interpretiert, wie es die Urheber der Metrik vorgeschlagen haben.
Betrachten wir als sehr einfaches und populäres Beispiel einer Pseudometrik die Produktivität. Sie ist definiert als die Größe der geleisteten Arbeit, bezogen auf die Arbeitszeit. Wenn also eine Gruppe in 310 Arbeitsstunden eine Software entwickelt, deren Code einen Umfang von 817 LOC hat, dann ist die Produktivität der Gruppe etwa 2,64 LOC/h. Dabei sind der Code-Umfang und die Arbeitszeit die Eingabegrößen, die Division ist die Rechnung, die Aussage, dass das Resultat die Produktivität darstellt, ist die Interpretation.
Ob diese Interpretation wirklich sinnvoll ist, kann man nur feststellen, wenn man die Produktivität in verschiedenen Projekten berechnet, vergleicht und auf Plausibilität prüft. Dabei wird man auf Mitarbeiter stoßen, die nach dem Eindruck aller Kollegen intensiv und erfolgreich arbeiten, aber nach dieser Metrik nur geringe Produktivität zeigen, weil sie die schwierigsten Aufgaben bekommen und oft von anderen um Rat gefragt werden. Hier ist die Plausibilität der Metrik offensichtlich nicht gegeben.
Solange man nicht davon überzeugt ist, dass die vorgegebene Interpretation wirklich sinnvoll ist, sollte man sprachlich zwischen der wirklichen und der berechneten Qualität x unterscheiden.
Die Metriken, insbesondere die Pseudometriken, können sich in verschiedenen Punkten unterscheiden.
Eine Metrik ist deskriptiv oder präskriptiv, sie beschreibt also einen Zustand, wie er ist, oder gibt vor, wie er sein soll. Beispielsweise ist im Cleanroom-Prozess (Abschnitt 10.5) eine Obergrenze für die Zahl der im Test entdeckten Fehler vorgegeben. Auch die Kostengrenze ist eine präskriptive Metrik.
Eine deskriptive Metrik kann diagnostisch oder prognostisch sein, also einen bestehenden oder einen zukünftigen Zustand beschreiben.
Eine Metrik kann robust oder unterlaufbar sein; eine robuste Metrik ist dadurch gekennzeichnet, dass die Entwickler keine Möglichkeit haben, die Werte der Metrik willkürlich zu beeinflussen.
Achtung, »präskriptiv« und »prognostisch« sind keine Synonyme, sondern schließen sich gegenseitig aus. Prognostische Metriken sind nicht präskriptiv, sondern deskriptiv, denn sie sagen nicht, wie die Zukunft werden soll, sondern wie sie (vermutlich) wird. In der Praxis ermittelt man zuerst mit einer prognostischen Metrik die zu erwartenden Werte (z. B. die Kosten), legt dann präskriptiv eine Grenze fest (im Beispiel das Entwicklungsbudget) und ermittelt später, ob die diagnostische Metrik (hier die aufgelaufenen Projektkosten) im Rahmen der präskriptiven geblieben ist (Soll-Ist-Vergleich).
Leider gibt es keine robusten Metriken. Falls der Entwickler vermutet, dass er mehr Anerkennung erhält, wenn er mehr Kommentare schreibt, wird er große Mengen sinnloser Kommentare produzieren. Ähnliches gilt auch für fast alle anderen Metriken. Einzig der Aufwand kann kaum nach unten verfälscht werden, weil der Entwickler seine Arbeitsstunden nachweisen muss. Durch Trödeln oder »Vergolden« der Software kann er den Aufwand aber fast beliebig hoch treiben.
Daraus folgt, dass man Metriken nur erfolgreich einführen kann, wenn die Software-Entwickler gut informiert sind und nicht befürchten müssen, dass bestimmte Resultate für sie Nachteile haben. Andernfalls werden sie die Metriken unterlaufen.
Die Komplexität eines Programms sollte im Interesse der Wartbarkeit so gering wie möglich sein. Aber was ist Komplexität?
complexity — (1) The degree to which a system or component has a design or implementation that is difficult to understand and verify.
Contrast with: simplicity.
(2) Pertaining to any of a set of structure-based metrics that measure the attribute in (1).
IEEE Std 610.12 (1990)
Für ein Programm bedeutet das, dass seine Komplexität als gering bewertet wird, wenn man es leicht verstehen und prüfen kann. Offenbar hat die Länge des Programms einen Einfluss darauf, aber sie ist, wie die beiden folgenden Auszüge eines in MODULA-2 formulierten Lehrbuchbeispiels (aus Appelrath, Ludewig, 2000) zeigen, keineswegs entscheidend:
(************************ A: DirektEinfuegen ************************)
PROCEDURE DirektEinfuegen;
VAR i, j : IndexTyp;
Zwischenspeicher : ElementTyp;
BEGIN (* DirektEinfuegen *)
FOR i := 2 TO MaxIndex DO
Zwischenspeicher := Sortierfeld [i];
Sortierfeld [0] := Zwischenspeicher;
j := i;
WHILE Zwischenspeicher < Sortierfeld [j-1] DO
Sortierfeld [j] := Sortierfeld [j-1]; DEC (j);
END (* WHILE *);
Sortierfeld [j] := Zwischenspeicher;
END (* FOR *);
END DirektEinfuegen;
(********************** B: Hauptprogramm ****************************)
BEGIN (* Sortieren *)
Generate (Kopie); Out (Kopie);
Erster := TRUE;
Check ("Direkt Aussuchen", DirektAussuchen);
Check ("Direkt Einfuegen", DirektEinfuegen);
Check ("Binaer Einfuegen", BinaerEinfuegen);
Check ("Bubble Sort", BubbleSort);
Check ("ShellSort", ShellSort);
Check ("HeapSort ", HeapSort);
Check ("QuickSort", QuickSort);
END Sortieren.
Die Größe der beiden Programme ist ähnlich: A (DirektEinfuegen) enthält insgesamt 548 Zeichen, ohne Kommentare, Leerzeichen und Zeilenwechsel sind es 304. Für B (Hauptprogramm) sind die entsprechenden Zahlen 469 und 297, also etwas niedriger. Die Zahl der Anweisungen ist aber bei B mit 10 höher als bei A (8).
Man könnte auf Grund dieser Zahlen vermuten, dass die Mühe, A und B zu verstehen, ähnlich groß ist. Tatsächlich ist aber B (abgesehen von der nicht erkennbaren Funktion der aufgerufenen Unterprogramme) trivial, weil es sich um eine einfache Sequenz handelt.
In der Graphentheorie gibt es die zyklomatische Zahl. Sie ist für einen zusammenhängenden Graphen G mit n Knoten und e Kanten definiert durch v(G) = e - n + 1. Eine anschauliche Deutung dieser Zahl ergibt sich, wenn man sich überlegt, wie viele Kanten man in einem Graphen streichen kann, ohne dass er den Zusammenhang verliert. Wenn man beispielsweise drei Knoten hat, die durch drei Kanten ringförmig verbunden sind, dann ist v(G) = 3 - 3 + 1 = 1. Wenn man eine (beliebige) Kante entfernt, hängen die drei Knoten noch über die beiden verbleibenden Kanten zusammen; nach dieser Veränderung ist v(G’) = 0, und es kann keine Kante mehr entfernt werden.
McCabe (1976) hat die zyklomatische Zahl als zyklomatische Komplexität für das Software Engineering entdeckt, indem er sie auf Flussdiagramme (Flussgraphen) anwandte. McCabes zyklomatische Komplexität ist wie folgt definiert:
v(G) = e - n + p
p ist darin die Zahl der Außenverbindungen. Im Standardfall eines Unterprogramms mit einem Ein- und einem Ausgang ist p also 2. Damit ist die Komplexität eines Programms minimal 1: e = 0, n = 1, p = 2. Zerlegt man einen Knoten in eine Sequenz, so ändert sich die Komplexität nicht, denn es kommen gleich viele Knoten wie Kanten hinzu.
Anschaulicher als die Formel ist die Vorstellung, dass eine lineare Verkettung von Anweisungen wie im Hauptprogramm B die Komplexität 1 hat; jede Verzweigung oder Schleife erhöht die Komplexität um 1. In der Flussdiagramm-Darstellung der Prozedur A (Abb. 14–4) sieht man die beiden Schleifen, die die Komplexität auf 3 steigen lassen.
Abb. 14–4 Beispiel für ein Flussdiagramm und dessen zyklomatische Zahl
Wir können feststellen, dass die zyklomatische Komplexität – wenigstens für diese kleinen Beispiele – ein Ergebnis liefert (3 für A, 1 für B), das die Komplexität von A und B wesentlich besser repräsentiert, als dies die oben genannten Größenangaben leisten.
v(G) lässt sich sehr leicht messen, man braucht nur ein Werkzeug, das – hier auf MODULA-2 bezogen – die Zahl der IF-, FOR-, WHILE- und CASE-Anweisungen feststellt. Jede dieser Kontrollstrukturen erhöht die Komplexität um eins, nur CASE um die Anzahl der Alternativen minus eins. Ein ELSE hinter IF und THEN hat keinen Einfluss. BEGIN wird als Eingang gezählt, AND und OR tragen als verkappte Bedingungsschachtelung jeweils 1 bei.
McCabe hat die Komplexität so definiert, dass er auch die – früher üblichen – Fälle von Programmen behandeln konnte, in denen das Prinzip »single entry, single exit« nicht eingehalten wurde. Heute können wir dieses Prinzip als verbindlich betrachten und haben damit in der Formel für v(G) immer p = 2. Das erweist sich als unglückliche Definition; es wäre sinnvoller gewesen, die 1 aus der Graphentheorie zu übernehmen, sodass ein unverzweigtes Programm die Komplexität null hat. Dann hätten wir eine normale Absolutskala vor uns und könnten beispielsweise bei der Verkettung von Programmen die Komplexitäten der Teilprogramme einfach addieren, um die Komplexität des Gesamtprogramms zu ermitteln.
Die zyklomatische Komplexität gehört zu den beliebtesten Metriken, vor allem, weil sie durch Zählung bestimmter Programmelemente wie IF und WHILE sehr einfach erhoben werden kann. Die für die Pseudometriken charakteristische Rechnung entfällt praktisch, es wird nur eine 1 addiert. Zudem ist die Metrik nicht (offensichtlich) von der Wahl der Programmiersprache beeinflusst. Diesen Vorteilen stehen allerdings auch einige Nachteile gegenüber: Die Metrik ist blind gegenüber den Daten, komplexe Datenstrukturen werden ignoriert. Damit hat ein Programm, in dem Zeiger verwendet und manipuliert werden, eventuell eine (scheinbar) geringe Komplexität, obwohl es sehr schwer zu verstehen ist. Zudem erschwert nicht jede Verzweigung das Verständnis in gleichem Maße, komplizierte Schachtelungen machen uns viel mehr Probleme als aufeinanderfolgende, aber jeweils abgeschlossene Alternativen; in der Metrik werden diese Fälle gleich gewichtet. Weyuker (1988) hat ebenfalls auf Mängel der Metrik hingewiesen.
Darum behauptet – vielleicht mit Ausnahme von Thomas McCabe – niemand, dass diese Metrik wirklich die Komplexität angibt. Vielmehr handelt es sich um eine einfache und einfach zu erhebende Volumensmetrik, die man an Stelle der LOC verwenden kann, beispielsweise, wenn man Systeme mit mehreren verschiedenen Programmiersprachen entwickelt; denn anders als die Zahl der Code-Zeilen ändert sich die zyklomatische Komplexität beim Wechsel zu einer anderen Programmiersprache kaum.
Relativ einfache Metriken wie die Komplexität nach McCabe sind anschaulich und können – vor allem in Relation zu anderen Metriken – extreme Situationen anzeigen, beispielsweise, wenn die Kombination aus einer hohen Komplexität und einer großen Zeilenzahl auf einen Strukturierungsfehler hinweist. Eine große Zeilenzahl ist höchstens dann zulässig, wenn es sich um strikt sequenziellen Code handelt, beispielsweise zur Vorbesetzung vieler Variablen.
Weiter gehende Schlüsse lassen sich daraus nicht ziehen, wenigstens nicht mechanisch. Maurice Halstead versuchte daher Mitte der Siebzigerjahre, komplexere Metriken zu definieren. Sein Ansatz war ausgesprochen ehrgeizig, und entsprechend mutig war der Titel seines Buches (»Software Science«, Halstead, 1977).
Halsteads Modell beruht auf der Vorstellung, dass Operatoren (wie +, /, AND) und Operanden (vordefinierte und neue Bezeichner) die Software prägen und dass die Daten dieser beiden Mengen die Software insgesamt charakterisieren. Er arbeitet daher mit vier Basisgrößen:
N1 ist die Zahl aller Operatoren im Programm
η1 ist die Zahl der verschiedenen Operatoren
N2 ist die Zahl aller Operanden im Programm
η2 ist die Zahl der verschiedenen Operanden
N = N1 + N2 bezeichnet er als die Länge des Programms (natürlich nicht die physische, sondern die abstrakte Länge).
Halstead postuliert nun verschiedene Zusammenhänge zwischen den vier Basisgrößen und anderen Größen. So gibt er beispielsweise für die abstrakte Länge eines Programms folgenden Zusammenhang an:
(ld: logarithmus dualis, d. h. Logarithmus zur Basis 2)
Wir zählen die Elemente der Prozedur A DirektEinfuegen nach den Regeln in Conte, Dunsmore und Shen (1986), Seite 36 ff. Diese Regeln beziehen sich auf PASCAL; da MODULA-2 ähnlich ist, können wir sie hier mit geringen Anpassungen verwenden. Die Details sind der Tabelle 14–7 zu entnehmen. Man beachte, dass Halstead selbst keine präzisen Angaben zur Zählung gemacht hat. Darum ist es sinnlos, nach den absolut richtigen Zählregeln zu suchen. Unsere Basisdaten sind damit:
Anzahl |
Operator |
1 |
PROCEDURE |
1 |
BEGIN END |
1 |
WHILE DO END |
1 |
FOR DO END |
1 |
TO |
1 |
DEC |
6 |
:= |
1 |
, |
2 |
- |
2 |
: |
12 |
; |
1 |
< |
1 |
() |
6 |
[] |
37 |
14 Operatoren (ohne VAR) |
Anzahl |
Operand |
|
DirektEinfuegen |
1 |
ElementType |
1 |
IndexType |
1 |
0 |
2 |
1 |
1 |
2 |
4 |
i |
7 |
j |
1 |
MaxIndex |
6 |
Sortierfeld |
5 |
Zwischenspeicher |
|
|
|
|
|
|
29 |
10 (ohne DirektEinfuegen) |
Tab. 14–7 Zählung der Elemente von DirektEinfuegen
η1 = 14, η2 = 10, N1 = 37, N2 = 29, N = N1 + N2 = 66
Diese Länge ist nicht wesentlich verschieden von der aus η1 und η2 berechneten, denn 14 ld 14 + 10 ld 10 = 53,3 + 33,2 = 86,5. Da wir hier nur den Ausschnitt eines Programms betrachten, müssen wir ohnehin mit gewissen Verzerrungen rechnen.
Ein anderes Beispiel ist der Programmieraufwand, den Halstead aus der Zahl der Elementarentscheidungen (E) ableitet, die ein Programmierer fällen muss. Diese gibt er an mit:
Für unsere Prozedur DirektEinfuegen errechnet sich die Anzahl der Elementarentscheidungen durch
Unter der Annahme, dass ein Programmierer etwa 18 Elementarentscheidungen pro Sekunde fällen kann4, ergibt sich daraus ein Zeitbedarf von 341 s oder knapp 6 min. Das dürfte wohl nur für einen sehr guten Programmierer zu schaffen sein.
Rechnet man weitere Beispiele durch, dann stellt man immer wieder fest, dass die Zahlen, die aus Halsteads Formeln resultieren, meist in der richtigen Größenordnung liegen. Sie sind aber nicht genauer als andere Abschätzungen. Halstead hatte seine Formeln damals auch nicht seriös validiert, sodass es kaum Gründe gibt, warum man seinen Resultaten vertrauen sollte. Aus heutiger Sicht ist eher überraschend, dass sie überhaupt in der richtigen Größenordnung liegen. Halstead konnte seine Arbeiten nicht mehr fortsetzen, er starb 1979.
Nachdem sich in den Achtzigerjahren die objektorientierten Programmiersprachen rasch verbreitet hatten, wurde in den Neunzigerjahren eine Reihe von Code-Metriken für objektorientierte Programme publiziert, die die neuen Programmierkonzepte berücksichtigen (z. B. Lorenz, Kidd, 1994; Henderson-Sellers, 1996).
Chidamber und Kemerer (1994) definieren in ihrer Arbeit sechs Metriken für objektorientierte Programme (siehe Tab. 14–8). Inzwischen gibt es sehr viele Werkzeuge, die diese Metriken ermitteln.
Berechnungsvorschrift |
|
weighted methods per class (WMC) |
|
depth of inheritance tree of a class (DIT) |
Tiefe der Klasse im Vererbungsbaum |
number of children of a class (NOC) |
Anzahl der direkten Unterklassen der Klasse |
coupling between object classes (CBO) |
|
response for a class (RFC) |
|
lack of cohesion in methods (LCOM) |
|P| - |Q| wenn |P| > |Q| sonst 0; mit den Mengen P und Q von Methodenpaaren, die kein (P) bzw. mindestens ein (Q) gemeinsames Attribut benutzen |
Tab. 14–8 Metriken von Chidamber und Kemerer
Basili, Briand und Melo (1996b) haben für einige dieser Metriken festgestellt, dass die Ergebnisse plausibel sind, dass also Programme, die auffällige Werte liefern, auch tatsächlich mehr Probleme machen als andere Programme. Man sollte diese Aussage aber nicht überschätzen. Die Erfahrung zeigt, dass schlechte Programme von sehr vielen verschiedenen Metriken erkannt werden. Wenn eine Klasse viel zu umfangreich ist, dann kann man das nicht nur leicht direkt sehen, sondern auch an fast jeder Zahl, die man erhebt, ablesen. El Emam et al. (2001) haben festgestellt, dass die Plausibilität der Metriken tatsächlich sehr gering ist, wenn der Einfluss der Klassengröße herausgerechnet wird. Insgesamt gibt es bei den Metriken für objektorientierte Programme noch eine Reihe von Unklarheiten. Einer der offenen Punkte ist, wie die Klassen zu behandeln sind, die als Rahmenwerke5, Klassenbibliotheken usw. nicht entwickelt, sondern verwendet werden. Zählt beispielsweise die Vererbungstiefe, die in dieser Infrastruktur steckt, bei der Ermittlung der Metrik DIT mit? Für beide möglichen Antworten gibt es gute Argumente. Darum kommt Kan zu dem Resultat:
... there seems to be agreement that it is far more important to focus on empirical validation (or refutation) of the proposed metrics than to propose new ones, ...
Kan (2003, S. 342 f.)
Drei der Metriken (DIT, NOC, CBO) sind objektive Metriken. Die anderen drei (WMC, RFC, LCOM) sind Pseudometriken. Nur bei LCOM ist allerdings die Interpretation wirklich klar: Ein Mangel an Zusammenhalt ist nicht erwünscht, der Zusammenhalt sollte so hoch wie möglich sein. Darum betrachten wir LCOM näher.
Eine Klasse hat einen hohen Zusammenhalt, wenn sie sinnvollerweise nicht aufgeteilt werden sollte, d. h., wenn ihre Attribute und Methoden einen einzigen zusammengehörenden Aspekt implementieren. (Den Zusammenhalt behandeln wir eingehend in Abschnitt 17.3.2.) Wie kann der Zusammenhalt einer Klasse auf Basis des Codes bestimmt werden?
Das der Metrik LCOM zu Grunde liegende Modell reduziert dazu eine Klasse darauf, inwieweit die Methoden die eigenen Attribute benutzen. Zuerst werden alle Methodenpaare gezählt, die kein gemeinsames Attribut verwenden. Von dieser Zahl wird dann die Anzahl der Methodenpaare abgezogen, die mindestens ein gemeinsames Attribut benutzen. Ist das Ergebnis negativ, dann liefert LCOM den Wert 0. Die Annahme hinter dieser Modellierung ist, dass Methoden, die keine gemeinsamen Variablen benutzen, möglicherweise einen unterschiedlichen Aspekt implementieren und nicht zur selben Klasse gehören sollten.
Kabaili et al. (2000) zeigen jedoch in einer Studie, dass aus dem mit LCOM errechneten Wert nicht auf den wirklichen Grad des Zusammenhalts geschlossen werden kann, die Metrik ist nicht plausibel. So gibt es Klassen mit einem hohen LCOM-Wert, deren Architektur gut ist. Auch liefert diese Metrik für Klassen, deren Zusammenhalt wir subjektiv ähnlich bewerten, sehr unterschiedliche Ergebnisse. Betrachten wir dazu das folgende Beispiel.
Die Klasse K1 definiere die beiden Attribute a1 und a2 sowie vier Methoden. Die Methoden m1 und m2 benutzen das Attribut a1, die Methoden m3 und m4 das Attribut a2. Die Klasse K2 sei ähnlich aufgebaut: Sie definiert ebenfalls zwei Attribute a1 und a2, jedoch zehn Methoden m1 bis m10. Die Methoden m1 bis m5 benutzen das Attribut a1, die Methoden m6 bis m10 das Attribut a2.
Beide Klassen haben demnach zwei disjunkte Gruppen von Methoden, die, wenn man lediglich die Attributnutzung betrachtet, nicht zusammengehören. Möglicherweise könnte man beide Klassen in je zwei Klassen aufteilen. Das spricht dafür, den Zusammenhalt für beide Klassen etwa gleich (schlecht) zu bewerten.
Wenden wir jedoch die Metrik LCOM auf diese beiden Klassen an, dann erhalten wir für K1: 4 - 2 = 2, für K2: 25 - 2 · 10 = 5. Das ist nicht plausibel.
Inzwischen wurde eine ganze Reihe von Vorschlägen publiziert, wie der Zusammenhalt von Klassen gemessen werden kann. Badri und Badri (2004) geben einen Überblick über diese Metriken und zeigen, dass neuere Metriken, die neben der Attributnutzung auch andere Aspekte berücksichtigen (z. B. inwieweit sich die Methoden einer Klasse gegenseitig nutzen), zu plausibleren Ergebnissen führen.
Bislang sind wir davon ausgegangen, dass der Anwender einer Metrik a priori weiß, welche Metriken er anwenden will. In diesem Abschnitt geht es darum, wie geeignete Metriken identifiziert und, wenn nötig, neu definiert werden können.
Wenn im Software Engineering Entscheidungen zu treffen sind (beispielsweise über Werkzeuge, über Änderungen des Prozesses oder über die zukünftige Gestaltung bestimmter Prüfungen), möchte man auf eine Datensammlung zugreifen, die die notwendigen Informationen enthält, also auf geeignete Metriken.
Praktisch ist es aber nicht möglich, für alle denkbaren Fragen Metriken auf Vorrat zu erheben. Basili und Weiss (1984) haben darum ein Konzept entwickelt, wie man die zu erhebenden Metriken aus den Problemen, Zielen und Fragen ableiten kann. Dieser Ansatz wird als Goal-Question-Metric-Approach (GQM) bezeichnet; er wurde in den Folgejahren erprobt und weiterentwickelt (Basili, Rombach, 1988; Basili, Caldiera, Rombach, 1994). GQM besteht, wie der Name sagt, aus drei Schritten:
1. Definiere die für ein Projekt oder für eine Organisation relevanten Ziele.
2. Leite aus jedem Ziel Fragen ab, die geklärt werden müssen, um überprüfen zu können, ob das Ziel erreicht ist.
3. Lege für jede Frage Metriken fest, die dazu beitragen, die Antworten auf die Fragen zu finden.
Wir demonstrieren dieses Vorgehen an einem Beispiel (van Solingen, Berghout, 1999): Eine Organisation, die seit längerer Zeit Code-Inspektionen durchführt, will die Wirksamkeit der Code-Inspektionen erhöhen, das heißt ohne höheren Aufwand mehr Mängel entdecken. Zu diesem Ziel lassen sich beispielsweise die folgenden Fragen stellen:
F1 |
Wie effektiv sind die Inspektionen? |
F2 |
Welche Merkmale muss ein Prüfling haben, damit eine Inspektion möglichst erfolgreich ist? |
F3 |
Welchen Qualitätskriterien soll ein Prüfling nach einer Inspektion genügen? |
Fragen auf dieser (oberen) Ebene sind noch zu komplex und abstrakt, als dass man ihnen direkt Metriken zuordnen könnte; sie müssen konkretisiert und verfeinert werden. Betrachten wir dazu die Frage F1; sie könnte folgendermaßen verfeinert werden:
Wie viel Aufwand pro Woche erfordern die Inspektionen? |
|
F1.2 |
Wie viele Fehler werden in einer Inspektion entdeckt? |
F1.3 |
Wie viele Fehler pro Fehlerklasse (leicht, mittel, schwer) werden entdeckt? |
F1.4 |
Wie viel Aufwand ist erforderlich, um einen Prüfling einer gewissen Komplexität zu inspizieren? |
F1.5 |
Wie viel Aufwand ist erforderlich, um einen Prüfling einer gewissen Größe zu inspizieren? |
Um diese Fragen zu beantworten, sind u. a. die folgenden einfachen Metriken hilfreich:
M1 |
Anzahl der entdeckten Fehler pro Inspektion |
M2 |
Anzahl der Inspektionen pro Woche |
M3 |
Aufwand pro Inspektion in Stunden |
M4 |
Anzahl der entdeckten Fehler pro Fehlerklasse pro Inspektion |
M5 |
Komplexität des Prüflings (z. B. als zyklomatische Komplexität) |
M6 |
Größe des Prüflings in LOC |
Diese Metriken können den Fragen zugeordnet werden; dadurch entsteht beispielsweise die in Abbildung 14–5 skizzierte Struktur.
Abb. 14–5 GQM: Zusammenhang von Zielen, Fragen und Metriken (Ausschnitt)
Natürlich genügt es nicht, die Ziele, Fragen und Metriken zu definieren. Anschließend müssen die Daten systematisch erfasst und im Hinblick auf die Fragen ausgewertet werden.
Der GQM-Ansatz ist populär, weil er verhindert, dass unsinnig viele oder irrelevante Metriken erhoben werden. Durch die Orientierung an einem bestimmten Ziel ist sichergestellt, dass die Metriken benötigt werden.
Die pragmatische Ausrichtung an einer konkreten Fragestellung ist aber auch ein Nachteil dieses Konzepts: In vielen Fällen ist es vorteilhaft, bestimmte Basisdaten regelmäßig und über lange Zeit zu erfassen, auch wenn es gerade keinen konkreten Bedarf gibt. Nur so kann man langfristige Trends erkennen. GQM reicht also nicht aus, auch eine gewisse vorsorgliche Datensammlung ist sinnvoll.
Die Entwicklung einer Pseudometrik vollzieht sich in folgenden Schritten:
1. Identifikation des darzustellenden Aspekts
Dieser Aspekt kann originär oder Teil eines übergeordneten Aspekts sein. Beispiele: Portabilität einer Software, das Betriebsklima im Projekt.
2. Modellierung des darzustellenden Aspekts
Hierzu muss von der Software oder dem Entwicklungsprozess so abstrahiert werden, dass ein auf den gewünschten Aspekt reduziertes Modell übrig bleibt. Beispiele:
• Für die Portabilität wird ein Programm so abstrahiert, dass nur noch zwei Arten von Anweisungen unterschieden werden, nämlich solche, die von der speziellen Plattform abhängig sind, und solche, die es nicht sind.
• Für das Betriebsklima wird die Tätigkeit der Mitarbeiter auf Einstellung und Kündigung durch den Mitarbeiter reduziert. Wird einem Mitarbeiter von der Firma gekündigt, so wird seine Einstellung nicht berücksichtigt.
3. Festlegung einer Skala für die Metrik
Der Skalentyp ist so zu wählen, dass er mit den im Modell verfügbaren Daten erreicht werden kann und den Aspekt ausreichend genau darstellt. In vielen Fällen genügt eine Ordinalskala. Beispiele:
• Die Portabilität soll als reelle Zahl zwischen 0 und 1 dargestellt werden (Rationalskala).
• Für das Betriebsklima wird eine Skala mit den Stufen schlecht – mäßig – gut – sehr gut definiert (Ordinalskala).
4. Entwicklung einer Berechnungsvorschrift
Diese bildet die im Modell enthaltenen Größen auf die Metrik ab. Beispiele:
• Die Portabilität ist (d. h. wird definiert als) das Verhältnis zwischen der Größe der plattformunabhängigen Anteile und der Programmgröße.
• Das Betriebsklima ist schlecht, wenn mehr als x % der Arbeitsverhältnisse in der Firma nach weniger als einer Dauer t von den Mitarbeitern gekündigt werden. Analog werden die Grenzen für die übrigen Stufen festgelegt. Die Konstanten x und t müssen sinnvoll gewählt werden.
5. Entwicklung der Messvorschriften für alle Größen, die in der Berechnungsvorschrift verwendet werden
Wenn subjektive Metriken verwendet werden, tritt an die Stelle der Messvorschrift die Anleitung zur Benotung. Beispiele:
• Die Zahl der Code-Zeilen (NCSI = non comment source instructions) wird als Maß der Größe verwendet.
• Das Maß für die Dauer eines Arbeitsverhältnisses ist die Zahl der vollen Beschäftigungsmonate. (Hier bleiben noch einige Sonderfälle zu klären ...)
6. Anwendung und Verbesserung der Metrik
Die Resultate werden mit den auf anderem Wege oder intuitiv ermittelten Bewertungen verglichen. Wenn nötig, wird die Metrik kalibriert und verbessert. Beispiele:
• Einige Wartungsprogrammierer benoten die Portabilität bestimmter Programme mit 0 bis 100 Punkten. Anschließend wird an diesen Programmen die Portabilitätsmetrik erhoben. Die Punkte werden in einem Koordinatensystem über den gemessenen Werten aufgetragen. Wenn die Punkte nicht nahe an einer Ursprungsgeraden liegen, ist die Metrik nicht plausibel.
• Die Metrik wird in verschiedenen Abteilungen angewendet; die Ergebnisse einer Umfrage in diesen Abteilungen werden mit den Einstufungen verglichen, die die Metrik liefert.
Wenn der Zusammenhang zwischen Modell und Metrik nicht so einfach und gut verstanden ist, wie der Schritt 4 erfordert, kann durch empirische Daten ein Zusammenhang konstruiert werden. So wurden beispielsweise die vielen in COCOMO enthaltenen Konstanten ermittelt.
In diesem Abschnitt wird gezeigt, wie aus allgemeinen Überlegungen die konkrete Definition einer Metrik abgeleitet werden kann. Als Beispiel wird eine Metrik für die Software-Zuverlässigkeit betrachtet. Dabei geht es nicht darum, einen Gegenvorschlag zu existierenden Metriken vorzulegen, sondern darum, die Schritte auf dem Weg zu einer Metrik zu zeigen und kritisch zu kommentieren.
Die Zuverlässigkeit ist ein besonders wichtiger Aspekt der Software, weil unzureichende Zuverlässigkeit extreme Kosten verursacht; nicht nur, wenn ein großes System spektakulär versagt, sondern auch, wenn viele kleine, billige Systeme nicht befriedigend funktionieren. Der Schnupfen ist keine schlimme Krankheit, aber er kostet die Volkswirtschaft trotzdem viel Geld, weil sehr viele Leute daran erkranken.
Es liegt daher nahe, absolute Zuverlässigkeit zu verlangen. Das ist ein verständlicher Wunsch, aber keine sinnvolle Forderung. Software wird von Menschen gemacht und ist daher niemals perfekt. Durch sehr hohen Aufwand kann die Zahl der unentdeckten Fehler immer weiter reduziert werden, es ist aber grundsätzlich unmöglich, Fehlerfreiheit zu garantieren. Zudem steigt mit höheren Anforderungen an die Zuverlässigkeit der Aufwand ins Unermessliche. Schließlich gibt es auch noch andere Komponenten, die versagen können, von der Rechner-Hardware über die Stromversorgung bis zum Kreislauf des Benutzers. Da keine dieser Komponenten absolut zuverlässig ist, wäre extreme Zuverlässigkeit der Software unwirtschaftlich.
Um eine Zuverlässigkeitsmetrik zu definieren, müssen wir wissen, was Zuverlässigkeit ist. Dazu schauen wir in die verfügbare Literatur. Im IEEE-Glossar ist die folgende Definition angegeben:
reliability — The ability of a system or component to perform its required functions under stated conditions for a specified period of time.
IEEE Std 610.12 (1990)
Diese durchaus angemessene Definition bildet jedoch keine ausreichende Grundlage, um eine Metrik für die Zuverlässigkeit zu entwickeln. Deshalb betrachten wir den in Abbildung 5–2 auf Seite 68 gezeigten Qualitätenbaum. Hier wird Zuverlässigkeit mit Hilfe dreier atomarer Qualitätsmerkmale wie folgt definiert:
Zuverlässigkeit = Korrektheit + Ausfallsicherheit + Genauigkeit
Für diese atomaren Qualitätsmerkmale gilt gemäß Tabelle 5–2 auf S. 69, dass
die Korrektheit hoch ist, wenn die Spezifikation zutreffend und die übrige Software korrekt in Bezug auf die Spezifikation ist,
die Ausfallsicherheit hoch ist, wenn die Software nur sehr selten die erwartete Funktion nicht erbringt,
die Genauigkeit hoch ist, wenn die Resultate vom mathematisch korrekten Resultat nur wenig abweichen.
Leider kommen wir auch mit diesen Begriffen einer Quantifizierung nicht näher. Wir beginnen also noch einmal ganz von vorn und überlegen, welche Bedeutung das Wort »zuverlässig« in unserer Alltagssprache hat.
Betrachten wir die folgende Liste von Gegenständen (im weitesten Sinne): Auto, Brieföffner, Briefpapier, Brille, Feuerzeug, Hammer, Handbohrmaschine, Hängebrücke, Lexikon, Mastkalb, Moskitonetz, Politiker, Telefon, Telefonbuch, Wettervorhersage, Ziegelstein.
Der Begriff Zuverlässigkeit lässt sich nicht auf alle genannten Gegenstände anwenden; er ist kaum anwendbar auf Brieföffner, Briefpapier, Brille, Hammer, Mastkalb und Ziegelstein. Wo er anwendbar ist, hat er nicht immer die gleiche Bedeutung. Für Lexikon, Politiker, Telefonbuch und Wettervorhersage bedeutet Zuverlässigkeit Verlässlichkeit und Korrektheit. Anders verhält es sich bei den Gegenständen Hängebrücke und Moskitonetz. Hier heißt Zuverlässigkeit Brauchbarkeit in dem Sinne, dass der Gegenstand »in Ordnung« ist. Wenn wir diese Interpretationen für die Software verwerfen, bleiben nur Auto, Feuerzeug, Handbohrmaschine und Telefon übrig.
Wir stellen fest: Der Begriff Zuverlässigkeit wird im engeren Sinne auf komplette Systeme angewendet, die komplexer Natur sind, grundsätzlich immer wieder für die gleiche Aufgabe eingesetzt werden und subjektiv stochastisch, also aus Gründen, die aus Sicht des Benutzers nicht erkennbar und kaum beeinflussbar sind, funktionieren oder versagen.
Ein solches System ist umso zuverlässiger, je höher die Erwartung ist, dass es seine Aufgabe erfüllt. Man beachte den Unterschied zwischen Zuverlässigkeit und Sicherheit. Ein Flugzeug, dessen Motor sich dann und wann nicht starten lässt, ist nicht zuverlässig, aber (wenn es sonst keine Probleme gibt) sicher!
Um eine Aussage über die Zuverlässigkeit machen zu können, müssen wir also einen stochastischen Prozess haben, der den Wahrscheinlichkeitsgesetzen folgt. Es muss eine abschätzbare Wahrscheinlichkeit geben, dass das System funktioniert.
Nehmen wir an, dass ein Rechnersystem inklusive Software völlig deterministisch arbeitet, dann ist die Wahrscheinlichkeit, dass es eine bestimmte Leistung erbringt, genau null oder genau eins. Der Zuverlässigkeitsbegriff kann darum nicht angewendet werden. Gleiches gilt (nahezu) für eine Leuchtdiode oder eine Brücke.
Wir müssen also irgendwo den Zufall einführen, um von Zuverlässigkeit sprechen zu können. Möglichkeiten dazu bieten der Benutzungsmodus, die Daten, die Speicherbelegung oder die Ressourcenzuteilung.
Wenn wir die Zuverlässigkeit eines Systems bewerten wollen, dann gehen wir eigentlich von der Unzuverlässigkeit des Systems aus, die wir beobachten können. Beispielsweise kann man die Abstände zwischen den Ausfällen messen. Wird ein Gegenstand immer in ähnlicher Weise eingesetzt (z. B. ein Telefon für bestimmte Verbindungen bestimmter Dauer), dann ist die mittlere Dauer zwischen zwei Defekten ein Maß seiner Zuverlässigkeit. Dieses Maß wird Mean Time Between Failure (MTBF) genannt und ist folgendermaßen definiert:
(Achtung: Da es für die MTBF unterschiedliche Definitionen gibt, können die berechneten Werte nicht immer direkt miteinander verglichen werden.)
Dabei muss die Betriebsdauer bis zum letzten Defekt gemessen werden. Bei Software ist dieses Maß nur dann anwendbar, wenn
die Fehler nicht korrigiert werden,
Art und Intensität der Benutzung gleich bleiben,
die Benutzer die Fehler weder provozieren noch vermeiden (d. h. faktisch, wenn die Benutzer die Fehler nicht kennen).
Eine wechselnde Intensität der Nutzung kann evtl. durch Normierung der Resultate berücksichtigt werden. Um die Unzuverlässigkeit der Software in den Griff zu bekommen, orientieren wir uns an der MTBF und definieren:
Unzuverlässigkeit ist die Zahl der Fehler, gewichtet mit der Häufigkeit ihres Auftretens und den Folgekosten, bezogen auf die Betriebsdauer.
Um die Unzuverlässigkeit bewerten zu können, benötigen wir also die Anzahl der Fehler, die Kosten, die die Fehler des betrachteten Systems verursachen, und die Betriebsdauer. Durch die Gewichtung mit den Kosten sorgen wir dafür, dass sich kleine und große Probleme unterschiedlich auf unsere Metrik auswirken. Wie aus diesen Angaben die Unzuverlässigkeit oder die Zuverlässigkeit bestimmt werden kann, zeigt das folgende Beispiel:
Eine Software S zeige während 2 h Benutzung im Mittel 10 Fehler zu je 0,40 € und einen Fehler zu 10 €. Die Unzuverlässigkeit der Software S ist dann:
Die Zuverlässigkeit kann man nun beispielsweise als Kehrwert von U definieren:
Jegliche Normierung erfordert eine (sinnvolle) Beseitigung der Dimensionen (praktisch: der Einheiten). In unserem Beispiel müssen also für Kosten und Zeit allgemeingültige Bezugsgrößen gefunden werden. Für die Zeit bietet sich die tägliche Betriebsdauer an (Annahme: DS = 8 h/d). Mehr Probleme machen die Kosten. Da wir die Unzuverlässigkeit als einen Teil der Kosten (im weitesten Sinne) empfinden, können wir die Betriebskosten des Systems als Bezugsgröße verwenden, wir rechnen mit Kosten von 100 € pro Tag (BS = 100 €/d). Die normierte Unzuverlässigkeit lässt sich nun bestimmen durch:
Das bedeutet: Die Unzuverlässigkeit der Software kostet uns 36 % der Betriebskosten, das sind 56 € pro Tag. Die normierte Zuverlässigkeit kann analog definiert werden durch:
Wenn die Software S während der Betriebsdauer im Mittel nur einen Fehler zu 10 € zeigt, dann ist die normierte Zuverlässigkeit nach diesem Modell 0,71; zeigt sie im Mittel nur die zehn leichteren Fehler zu je 0,40 €, steigt die Zuverlässigkeit auf 0,86.
Damit haben wir eine Metrik; es ist offensichtlich, welche Daten erfasst und verarbeitet werden müssen, um die Metrik systematisch zu erheben. Ob die Definition aber (allgemein oder für eine spezielle Situation) sinnvoll ist, wissen wir noch nicht. Wenn wir einige Szenarien durchspielen, sehen wir, dass die Zuverlässigkeit steigt, wenn die Betriebskosten unseres Systems steigen. Ist das sinnvoll, plausibel? Oder deutet der Effekt auf eine unsinnige Normierung? Wir sehen: Die Definition einer Metrik ist schwierig und hat oft überraschende Konsequenzen.
Als in der Physik Begriffe wie »Kraft« und »Energie« definiert wurden, hatten sie noch keine allgemein anerkannte Bedeutung. Die sehr bequeme Situation, mit einem perfekt abgestimmten System von Größen und Einheiten arbeiten zu können, ist erst im Laufe der Zeit entstanden.
Im Software Engineering ist ein solcher Zustand noch nicht in Sicht. Wir sind noch auf der Suche nach den Größen und Einheiten, die sinnvoll definiert und verwendet werden können. Trotzdem gibt es in der Literatur bereits eine lange Liste von Metriken und sogar genormte Metriken.
Wenn man von einem GQM-Ansatz ausgeht, ergibt sich die Antwort aus den Fragen, die man zu den Zielen formuliert; der verbleibende Spielraum ist gering, er sollte so genutzt werden, dass die Erhebung der Metriken möglichst einfach und sicher geschehen kann.
Hat man dagegen vor, Basisdaten auf Vorrat zu sammeln (siehe Abschnitt 14.2.2), ist die Auswahl größer. Es ist zweckmäßig, mit den drei allerwichtigsten Größen, nämlich Umfang, Aufwand und Fehlerzahlen, zu beginnen:
Umfang
In aller Regel wird der Umfang des Codes gemessen, weil dies viele Werkzeuge automatisch tun. Wie die Angaben in Tabelle 14–3 zeigen, gibt es jedoch sehr verschiedene Möglichkeiten, den Umfang von Programmen zu bestimmen. Wer vor der Wahl steht, sollte bedenken, dass die Entscheidung sehr wahrscheinlich Einfluss auf die Programmierung hat. Werden beispielsweise die NCSI gezählt, die non-comment source instructions, dann kommt bei vielen Entwicklern die Botschaft an: Kommentare werden hier als wertlos betrachtet. Es spielt keine Rolle, ob das wirklich so ist! Darum ist die anzuwendende Definition des Umfangs mit Bedacht zu wählen.
• Bei Wartungsarbeiten sollte zusätzlich der Umfang des geänderten Codes gemessen werden.
• Metriken kann man nicht nur auf Programme anwenden. Auch der Umfang der separaten Dokumentation (siehe Abschnitt 12.1) sollte bestimmt werden. Als Maß kann beispielsweise die Zahl der Zeichen und Abbildungen oder die Zahl der Seiten verwendet werden.
Aufwand
Für jedes Projekt und für jedes Arbeitspaket sollte der geleistete Aufwand festgehalten werden. Dadurch ist u. a. auch der Aufwand für die Prüfungen dokumentiert. Ebenso sollte man den Aufwand für Wartungsarbeiten erfassen.
Fehlerzahlen
Hier sind wenigstens die Anzahl der durch Prüfungen gefundenen Fehler und die nach Auslieferung gemeldeten Fehler zu zählen.
Mit Hilfe dieser wenigen Basisdaten lassen sich beispielsweise die folgenden Metriken erheben:
Fehlerrate pro Release
Fehlerdichte
Mittlerer Aufwand pro entdecktem Fehler im Test oder im Review
Mittlerer Aufwand zur Fehlerkorrektur nach Auslieferung
Kommen mehrere Metriken in Frage, so sollte man die einfachste nehmen, beispielsweise für die Größe eines Programms die Angabe in LOC. Kompliziertere Metriken sollten die einfachen dann und nur dann verdrängen, wenn sie klare Vorteile haben; Lind und Vairavan (1989) haben aber in einem (noch immer aktuellen) Artikel gezeigt, dass die gängigen Metriken untereinander stark korreliert sind, also im Wesentlichen die gleichen Resultate liefern.
Wenn es standardisierte Metriken gibt, sollten wir nicht ohne Not davon abweichen, denn sie sind sehr wahrscheinlich sinnvoll definiert und (anders als jede »private« Metrik) allgemein oder doch von vielen Menschen akzeptiert. Hier sind zwei Quellen zu nennen:
In der Norm ISO/IEC 9126 (Software Engineering – Product quality) wird eine Reihe von Produktmetriken beschrieben, um die ebenfalls in der Norm definierten Produktmerkmale Funktionalität, Zuverlässigkeit, Bedienbarkeit, Effizienz, Wartbarkeit und Portabilität zu messen. Diese Metriken werden, weil sie standardisiert sind, auch häufig von Messwerkzeugen ermittelt.
Der Standard IEEE Std 982.1 (1988) (Dictionary of Measures to Produce Reliable Software) enthält genaue Definitionen verschiedener Metriken, um die Zuverlässigkeit von Software zu messen; dazu zählen Fehlerdichte und MTBF (Mean Time Between Failure).
Sollen Metriken systematisch und organisationsweit erhoben werden, dann muss ein geeigneter Prozess definiert und angewendet werden. Die Normen ISO/IEC 15939 (2007) (Systems and software engineering - Measurement process) und IEEE Std 1061 (1998) (Standard for a Software Quality Metrics Methodology) können dabei hilfreich sein. Sie beschreiben recht detailliert einen generischen Prozess, um Metriken auszuwählen, Messungen durchzuführen und die erhobenen Daten auszuwerten. Der in der Norm ISO/IEC 15939 definierte Prozess sieht beispielsweise die folgenden Aktivitäten und Subaktivitäten vor:
Establish and sustain measurement commitment
• Accept the requirements for measurement
• Assign resources
Plan the measurement process
• Characterize organizational unit
• Identify information needs
• Select measures
• Define data collection, analysis, and reporting procedures
• Define criteria for evaluating the information products and the measurement process
• Review, approve, and provide resources for measurement tasks
• Acquire and deploy supporting technologies
Perform the measurement process
• Integrate procedures
• Collect data
• Analyze data and develop information products
• Communicate results
Evaluate measurement
• Evaluate information products and the measurement process
• Identify potential improvements
Dieser Prozess kann als Vorlage verwendet werden, um Metriken und Messungen in einer Organisation einzuführen und zu etablieren. Insbesondere kann man Aktivitäten und Dokumente übernehmen.
Ein Blick in diese Normen lohnt sich praktisch immer und kann viel Aufwand sparen.