Sorgfältige und genaue Planung ist eines der Hauptmerkmale des PSP. Dazu gehört insbesondere eine gute Schätzung des (Zeit)Aufwandes für ein Projekt. Diese Schätzung wird im PSP auf dem Umweg über die Größe des entstehenden Programms vorgenommen, weil davon ausgegangen wird, daß erstens die Anforderungen bereits bekannt sind und zweitens die Entwicklungszeit dann recht gut mit der Größe korreliert. Diese Annahmen sind innerhalb des üblichen Anwendungsbereichs des PSP oftmals gut erfüllt.
Das große Problem beim Schätzen ist ganz allgemein, daß einerseits eine Schätzung möglichst früh gemacht werden soll, andererseits eine genaue Schätzung Informationen über Details benötigt, die so früh noch nicht vorhanden sind. Es gilt also, eine Möglichkeit zu finden, wie man das nötige Maß von Detailinformationen durch anderes ersetzen kann, um auch ohne sie zu einer genauen frühen Schätzung zu kommen. Um das zu erreichen, muß man auf direktes Schätzen verzichten und stattdessen die Schätzung über einen Vergleich mit Bekanntem vornehmen. Auf diese Weise lassen sich historische Daten über frühere Entwicklungsarbeiten nutzbringend in der Schätzung einsetzen.
Gehen wir einmal davon aus, daß wir eine Entwicklung in einer objektorientierten Programmiersprache schätzen sollen (andernfalls läßt sich das Verfahren anpassen, indem wir Module statt Objektklassen benutzen etc.). Dann funktioniert das PSP-Größenschätzverfahren folgendermaßen: Ausgangspunkt der Schätzung ist ein sogenannter konzeptueller Entwurf. Ein solcher identifiziert die Hauptkomponenten, die zur Lösung des Problems vermutlich benötigt werden, z.B. auf der Ebene von Objektklassen und beschreibt grob deren Funktionalität. Der Zweck des konzeptuellen Entwurfs ist lediglich die Größenschätzung; er stellt keine Festlegung des tatsächlichen Entwurfs dar, obwohl er in der Regel natürlich eine gute Grundlage dafür bildet. Bei größeren Aufgaben kann die Herstellung eines konzeptuellen Entwurfs eine beträchtliche Arbeit sein, die mehrere Tage dauert, weil man bis zu einer Ebene von Komponenten herunterbrechen muß, die man gut schätzen kann; aber in jedem Fall steht der Aufwand in einem sinnvollen Verhältnis zum Gesamtaufwand. Im konzeptuellen Entwurf läßt sich auch etwa abschätzen, welche Teile eines bestehenden Programms als Basisprogramm übernommen werden können und wie umfangreich die Änderungen daran sind, wenn das Problem die Erweiterung eines bestehenden Programms ist, und wie viele andere bestehende Komponenten in welchem Gesamtumfang unverändert wiederverwendet werden können.
Die Schätzungen von Basis, Löschungen, Modifikationen, Zufügungen und neuen Objekten werden zusammengerechnet und ergeben die initiale Schätzung. Diese wird schließlich mit Hilfe historischer Daten über die Genauigkeit früherer Schätzung korrigiert, indem man eine lineare Regression berechnet, die die initiale Schätzung auf die wirkliche Schätzung abbildet. Diesen Schätzprozeß werden wir nun etwas genauer besprechen, wobei wir uns auf folgendes Beispiel beziehen:
Base Program LOC Base size (B) 295 LOC deleted (D) 25 LOC modified (M) 30 Projected LOC (P) Base_additions (BA) (Type) (#meth) (size) LOC readFromNetwork 40 openAgain 15 Total_base_additions ___________________________ 55 New_objects (NO) Type #meth size LOC Networkcomm I/O 10 M 160 BasicNetwork I/O 8 S 96 Crypt Comp 3 L 75 Total_new_objects (NO)__________________________ 331 Reused objects LOC Longint 780 Reused_total (R) 780 Estimation: Projected LOC (P) BA+NO 386 Estimated New&changed LOC (N) beta0+beta1(P+M) 488 Estimated total LOC (T) B+N-D-M+R 1508 Prediction interval 448 - 528 Prediction interval level (%) 70
Hierbei handelt es sich um ein Schätzformular, das im Laufe der Schätzprozedur ausgefüllt wird. Nun also das Vorgehen noch einmal in Schritten:
Mit Hilfe einer zweiten linearen Regression kann man jetzt eine Umrechnung der geschätzen Größe in die zu erwartende Entwicklungszeit vornehmen, so daß man auch gleich eine Aufwandsschätzung erhält; siehe den Abschnitt 6.6.4.
Der Trick bei dieser Schätzmethode ist die geschickte Auswahl von Stellvertretern (Ersatzgrößen), um auf das in der Schätzphase noch fehlende Detailwissen verzichten zu können ohne viel Schätzgenauigkeit einzubüßen. Anstatt direkt den Umfang zu schätzen, benutze ich eine Zerlegung in Teile, die ich mir noch recht gut vorstellen kann. Ich schätze deren Größe dann zum Teil intuitiv, indem ich nur fünf grobe Größenklassen verwende, und benutze historische Daten, die den Inhalt meiner Intuition widerspiegeln, um zu einer guten Schätzung zu gelangen.
Wie kommt man nun zu sinnvollen LOC-Werten für die einzelnen Größenklassen? Ausgangspunkt ist die Überlegung, daß die Werte möglichst meine intuitive Vorstellung davon, was ,,klein`` oder ,,mittel`` etc. ist, wiedergeben sollten. Diese Vorstellung hängt von Häufigkeiten ab: Das, was oft vorkommt, ist mittel, etwas größeres, was nur mäßig oft vorkommt, ist groß, und nur etwas recht seltenes kann sehr groß genannt werden; für klein und sehr klein geht es analog.
Für eine Normalverteilung lassen sich recht einfach einleuchtende Bereiche für eine solche Einteilung angeben: Etwa 38.3% aller Fälle liegen im Bereich von plus oder minus einer halben Standardabweichung um den Mittelwert, also in einem Bereich der Breite einer Standardabweichung; diese nenne ich ,,mittel``. Als ,,groß`` bzw. ,,klein`` bezeichne ich die Bereiche, die mehr als eine halbe, aber weniger als eineinhalb Standardabweichungen vom Mittelwert entfernt liegen; diese umfassen je 24.2% aller Fälle. Die verbleibenden zweimal 6.7% aller Fälle verteilen sich auf die Bereiche, die mehr als eineinhalb Standardabweichungen vom Mittelwert entfernt sind; diese nenne ich ,,sehr groß`` und ,,sehr klein``.
Also rechnen wir einfach Mittelwert m und Standardabweichung s unserer Methodengröße aus und erhalten die Grenzen der Bereiche wie oben angegeben? Als Schätzwerte für die Bereiche könnten wir dann deren Mitte verwenden, also m-2s, m-s, m, m+s, m+2s.
Leider nein, so geht es nicht, denn Methodengrößen sind üblicherweise nicht normalverteilt. Aber sie sind meistens ungefähr log-normal verteilt, so daß wir uns mit einem Trick behelfen können. Log-normale Verteilung bedeutet, daß die Logarithmen der Werte eine Normalverteilung haben. Dieser Effekt tritt sehr oft bei Größen auf, die zwar eine natürliche untere Schranke haben (zum Beispiel Null), aber keine obere und die dieser unteren Schranke häufig nahekommen. Somit können wir die ganze obige Prozedur mit den Logarithmen der Methodengrößen vornehmen und am Schluß delogarithmieren, um die Schätzgrößen jeder Größenklasse zu erhalten.
Beispiel: Gegeben sei eine Reihe von Klassen, die unsere historischen Daten für eine bestimmte Klassenart repräsentieren. Die Werte für die LOC pro Methode lauten für diese 13 Klassen 10.33, 6, 21.75, 29, 8.33, 6, 22.25, 28.33 12.33, 55.8, 20.5, 16.4, 23. Das ergibt einen Mittelwert von 20 und eine Standardabweichung von 12.84. Die zugehörigen Logarithmen (wir verwenden hier den natürlichen Logarithmus, man könnte aber auch einen anderen benutzen) lauten 2.335, 1.792, 3.08, 3.367, 2.12, 1.792, 3.102, 3.344, 2.512, 4.022, 3.02, 2.797, 3.135. Hier sind der Mittelwert 2.802 und die Standardabweichung 0.6346.
Wir erhalten also als Bereichsgrößen im logarithmischen Bereich (also
in der Maßeinheit logLOC) die Werte
VS = 2.802 - 2*0.6346 = 1.533
S = 2.802 - 0.6346 = 2.167
M = 2.802
L = 2.802 + 0.6346 = 3.437
VL = 2.802 + 2*0.6346 = 4.071
und durch berechnen des inversen Logarithmus erhalten wir daraus für den
nichtlogarithmischen Bereich (also in der Maßeinheit LOC) die Werte
VS = exp(1.533) = 4.63
S = exp(2.167) = 8.73
M = exp(2.802) = 16.48
L = exp(3.437) = 31.09
VL = exp(4.071) = 58.62
Wie wir sehen, sind die Werte von VS und VL jenseits des Bereichs, der von den Daten überhaupt erreicht wird (6.0 bis 55.8). Das ist nicht verblüffend, denn bei 13 Datenwerten repräsentiert ein Wert immerhin 7.7% und der ganze VS- bzw. VL-Bereich deckt ja nur 6.7% aller Werte ab.
Vor der Anwendung der beschriebenen Methode sollte man sicherstellen, daß die benutzten Daten auch tatsächlich eine ungefähr lognormale Verteilung haben. Dazu ist insbesondere zu fordern, daß genügend Daten vorhanden sind; mit viel weniger als den obigen 13 Punkten sollte man nicht anfangen. Wenn nicht genügend Werte da sind, kann man entweder die Größenbereiche per Intuition schätzen (oder die berechneten per Intuition korrigieren) oder gleich die Schätzung nicht über einen Größenbereich ausrechnen, sondern direkt vornehmen, also ,,diese Klasse hat vermutlich 10 Funktionen zu je, sagen wir mal 20 Zeilen``.
Warum soll man die Einteilung der Objektgrößenklassen getrennt für verschiedene Arten von Objektklassen vornehmen? Weil diese recht unterschiedliche Eigenschaften haben können im Hinblick nicht nur auf die absoluten Größen, sondern auch auf die Streuung zwischen den Größenklassen. Hier als Beispiel die Werte, die Humphrey für seine eigenen Größenklassen für C++ angibt:
Art VS S M L VLDie Berechnungsklassen haben also zwar geringere ,,klein``- und ,,mittel``-Größen, aber dennoch größere ,,groß``-Größen, weil ihre Streuung erheblich breiter ist als bei den Ein-/Ausgabeklassen.
Comp 2.3 5.1 11 25 54
I/O 9 12 16 22 29
Der Verwendung der linearen Regression liegen zwei Überlegungen zugrunde.
Die Korrektur dieser zwei Teile des systematischen Fehlers leistet die lineare Regression. In der Terminologie des Abschnitts über Vorhersagesysteme (1.6.1) suchen wir also ein Vorhersagesystem zur Vorhersage der tatsächlichen Größe aus der geschätzten Größe. Wir verwenden dafür als Modell die Vorstellung ,,wenn Du als Größe s geschätzt hast, dann beträgt die tatsächliche Größe g = a*s + b``. Die Berechnungsprozedur zur Bestimmung der günstigsten Werte für a und b ist die lineare Regression auf Basis vergangener tatsächlicher Paare von Schätzung und wirklicher Größe. Die Berechnung geht genauso vor sich, wie im obenerwähnten Abschnitt gezeigt.
Solange die historischen Daten noch knapp sind, kann sich durch jeden neuen Datenpunkt eine spürbare Veränderung im Vorhersagesystem ergeben. In diesem Fall sollte das Vorhersagesystem also für jede Schätzung neu berechnet werden und zwar unter Verwendung aller bisher vorhandenen Datenpaare. Im Laufe der Zeit werden dann Änderungen immer seltener nötig, nehmen jedoch noch einen zusätzlichen Zug an: Nach einer Weile wird sich die Schätzpraxis verändern, weil man mehr und mehr Erfahrung im Schätzen sammelt. Dann spiegeln alte Datenpaare nicht mehr die gegenwärtige Schätzpraxis wider und sollten lieber nicht mehr bei der Berechnung des Vorhersagesystems benutzt werden. Es werden also im Laufe der Zeit nicht nur neue Datenpaare bei der Berechnung mit eingeschlossen, sondern irgendwann auch alte ausrangiert. Welche das sind und wann man sie ausschließt, bleibt dem Urteilsvermögen überlassen, wobei man sich durch eine graphische Betrachtung der Punktwolken der jüngsten und ältesten Datenpaare (in zwei verschiedenen Farben) helfen kann: Liegen die Punktwolken deutlich getrennt, so hat sich tatsächlich etwas geändert und die alten Punkte sollten nicht mehr benutzt werden.
Aus der Größenschätzung kann man ebenfalls mit einer linearen Regression auch eine Zeitschätzung erhalten, wenn man genügend historische Daten über diesen Zusammenhang hat und diese Daten eine ausreichend hohe Korrelation zwischen den beiden Größen zeigen, was üblicherweise der Fall ist, wenn die Größe anständig geschätzt wird.
Diese Berechnung ist genau der Fall, der im Abschnitt 1.6.1 besprochen wurde, nur daß nicht tatsächliche Größendaten als Eingabe dienen, sondern Größenschätzungen.