Content uploaded by Reinhard Fößmeier
Author content
All content in this area was uploaded by Reinhard Fößmeier on Nov 08, 2015
Content may be subject to copyright.
Kohäsion als Leitlinie der Objektorientierung
R. FÖSSMEIER
Akademio Internacia de la Sciencoj (AIS) San-Marino
IXOS AG, Grasbrunn
ZUSAMMENFASSUNG
Diese Arbeit zeigt, wie die Entwurfsprinzipien der OO-Programmierung sich überwiegend auf das Prinzip der Lokalität (Vermeidung
von Kopplung über große notationelle Distanz) zurückführen lassen und wie das Anstreben hoher Lokalität die Richtung zu besserer
Kohäsion (Modulstärke) weist. Darauf aufbauend gibt sie Hinweise, wie sich diese Begriffe als Leitlinien beim Software-Entwurf
und auch bei der Kodierung dazu einsetzen lassen, gut lesbare und wartungsfreundliche Programme entstehen zu lassen.
SUMMARY
It is demonstrated how the principles of object-oriented design and programming can be derived from the principle of locality (ab-
sence of coupling over large notational distance), and how striving for high locality can lead the way to better cohesion (module
strength). Furthermore it is pointed out how these concepts can serve as guidelines during software design as well as during coding in
order to ensure legibility and maintainability of programs.
RESUMO
La artikolo montras, kiel la desegnaj principoj de la objektema programado plejparte estas deriveblaj de la principo de lokeco (evito
de kuplado trans grandaj distancoj), kaj kiel strebado al alta lokeco gvidas la vojon al pli bona kohereco (modjula forteco). Surbaze
de tio la teksto indikas kiel apliki tiujn nociojn dum la desegnado kaj same dum la kodado cele al bone legeblaj kaj mastrumeblaj
programoj.
1 EINLEITUNG
1.1 Kohäsion und Kopplung
Der Begriff der Kohäsion oder des Zusammenhalts
(engl. cohesion) im Software-Entwurf wurde offenbar
zuerst um 1979 von Yourdon und Constantine [14]
eingeführt, ist aber in der Definition identisch mit dem,
was Myers [10] bereits 1975 als module strength
bezeichnet, nämlich
„ein Maß für die Stärke der funktionalen
Bindung von Aktivitäten oder Sachverhalten in
einer Betrachtungseinheit.“ [5]
Myers‘ Einteilung der Arten der Kohäsion (funktional,
sequentiell, kommunikativ, prozedural, zeitlich, logisch,
zufällig) und ihre Bewertung sind bereits klassisch
geworden. Man kann sie als Gründe auffassen, warum
bestimmte Dinge in einer „Betrachtungseinheit“ oder
einem Modul zusammengefasst sind. Module eines gut
modularisierten Systems zeichnen sich damit durch
„funktionale“ (= hohe) Kohäsion aus; die Bindungen
gehen nicht über das Maß dessen hinaus, was die
funktionalen Anforderungen bedingen. Um es kürzer
auszudrücken: die Module sind nicht größer als not-
wendig.
Wie geht der kohäsionsbewusste Softwareentwickler
beim Programmentwurf vor? Er klassifiziert die Kohä-
sion seiner Module, bestimmt also, warum bestimmte
Modulteile beieinander stehen, und versucht bei schwa-
cher Kohäsion, die Teile in eigene, überschaubarere
Module auszugliedern. Beides, die Analyse und die
resultierenden Änderungen, sind meist anspruchsvolle
Aufgaben, die Erfahrung erfordern.
Das Streben nach funktionaler Kohäsion ist also eine
Methode, um durch Analyse inhaltlicher Programm-
eigenschaften zu einer besseren Programmstruktur zu
kommen. „Besser“ heißt dabei einerseits inhaltlich
besser verständlich und andererseits auch formal besser
überschaubar.
1.2 Lokalität
Bereits bei Yourdon und Constantine [14] findet sich
auch der Hinweis, dass es „eine grundlegende Methode
der Entkopplung ist, die Effekte der Kopplung durch
gemeinsame Umgebung durch Lokalisierung zu verrin-
gern“ („one very essential method of decoupling is to
reduce the effects of common-environment coupling by
localization“, Hervorhebung im Original). Mit anderen
Worten: Größen, die nur in einem engen Bereich gültig
sind, können nicht zu Kopplung mit entfernten
Programmteilen führen.
Diese „grundlegende Methode“ klingt so trivial, dass sie
in der Praxis kaum noch Erwähnung findet; sogar in
Lehrbüchern sucht man sie weithin vergeblich. Die
Ausdrücke „Lokalisierung“ und „Lokalität“ werden in
525
der Informatik überwiegend mit anderen Bedeutungen
verwendet1. Für die Eigenschaft, dass inhaltlich zusam-
menhängende Teile auch notationell nahe beieinander
stehen, wird gelegentlich der Ausdruck „Proximität“
verwendet. Brough [2] definiert die beiden Begriffe
folgendermaßen, wobei er im Gegensatz zu Yourdon
und Constantine die Lokalität hauptsächlich auf
grafische Darstellungen bezieht:
Locality principle: the desirability (in a graphic
view) of each fact seen in the view being
reviewable by referring to items that are 'close to
each other'. If the view doesn't have this
property, it is very difficult to understand it, as
items in one part of it must be 'remembered',
when looking at other parts of it. If the locality
principle is adhered to, facts can be taken in 'at a
glance'.
Note: a similar 'proximity principle' holds with
other views types (sound, text, ...), but it is most
familiar with diagrams.
Inhaltlich orientierte Techniken zur Auffindung „guter“
Modulstrukturen finden zunehmend Eingang in die
Informatikausbildung; hier sind zum Beispiel Entwurfs-
muster (engl. design patterns) zu nennen. Dagegen
werden einfache formale Grundsätze wie Lokalität und
Proximität so sehr vernachlässigt, dass viele Informati-
ker wie vor zwanzig Jahren alle Variablen eines Unter-
programms zu dessen Beginn deklarieren und Methoden
schreiben, die sich über viele Seiten erstrecken. Solche
Praktiken finden sich auch in verbreiteter, sogar
kommerziell vertriebener Software2.
2 LESBARKEIT ALS PROGRAMMQUALITÄT
Wo die Wartbarkeit eines Programms als Qualitäts-
eigenschaft im Vordergrund steht, wird stets gute Les-
barkeit angestrebt. Selbst der Autor eines Programms ist
ja darauf angewiesen, dieses bei späterem Lesen erneut
zu verstehen. Hofmann formuliert das so:
Es soll jeweils mit kleinstmöglichem Leseaufwand
möglich sein, die begrifflichen Bedeutungen zu
verstehen. [5]
Dabei ist es von entscheidender Bedeutung, dass die
Kapazität des menschlichen Bewusstseins sehr begrenzt
1 „Lokalisierung“ bezeichnet meist die Anpassung eines
„internationalisierten“ Programms an eine bestimmte
Dialog- oder Ausgabesprache; „Lokalität“ bezeichnet in
der Parallelprogrammierung ein Speicherzugriffsver-
halten, das häufige Wechsel zwischen weit entfernten
Adressen vermeidet. Interessanterweise kann ein Man-
gel an dieser Art von Lokalität auch die hier behandelte
beeinträchtigen, wenn die dadurch notwendigen Anwei-
sungen zur Synchronisierung des Speicherzugriffs die
Objektklassenstruktur durchbrechen („Vererbungs-
anomalie“) [12].
2 Die Java-Klassen des AWT-Systems sind hier teilweise
ein Negativbeispiel; man betrachte etwa die Methode
GridBagLayout::GetLayoutInfo().
ist. Dies beweisen außer der individuellen Erfahrung die
bereits klassischen Untersuchungen von Miller [9]
sowie von Lehrl et al. [7,8]. Jedes Programmelement,
das der Leser unnötigerweise im Bewusstsein behalten
muss, erschwert daher das Lesen. Ein simples Beispiel
zeigt Abbildung 1: In der linken, notationell knapperen
Notation muss der Leser zunächst den Sachverhalt
„Variable tmp ist nicht initialisiert“ und nachher
„Variable tmp enthält den Wert von y“ im Gedächtnis
behalten, bis er irgendwann zu dem Schluss kommt:
„tmp“ hat nur über drei Zeilen des Programms hinweg
Bedeutung“. Auf der rechten Seite wird diese Tatsache
unmittelbar klar.
int tmp;
...
tmp = x;
x = y;
y = tmp
...
...
{
const int tmp = x;
x = y;
y = tmp;
}
...
Abbildung 1: Vertauschen mittels einer temporären
Variable
Noch deutlicher wird der Zusammenhang, wenn man
das Lesen des Programms als das Sammeln von
Informationen über Zusammenhänge betrachtet. Bevor
man das Programm gelesen hat, kann jede Stelle, die
eine Variable verändert, jede Stelle beeinflussen, wo die
Variable verwendet wird. Umfasst der Gültigkeits-
bereich einer Variable m Anweisungen, so sind das rund
m2 Zusammenhänge, und erst während des Lesens stellt
sich heraus, welche davon bestehen und welche nicht.
Alles, was den Gültigkeitsbereich kleiner macht (die
Lokalität erhöht), reduziert a priori die Komplexität für
den Leser. Und die Verwendung von konstanten
Variablen (wie in Abbildung 1 rechts) reduziert die
wertverändernden Stellen auf eine, so dass es nur noch
m statt m2 mögliche Zusammenhänge gibt (vgl. [3]).
3 OO UND LOKALITÄT
Wie grundlegend hohe Lokalität für die Qualität eines
Softwareentwurfs ist, zeigt eine Untersuchung des
Zusammenhangs zwischen Lokalität und Objekt-
orientierung. Die charakteristischen Eigenschaften und
Techniken der OO-Programmierung lassen sich
großenteils auf das Streben nach Lokalität zurück-
führen.
Betrachten wir das bekannte Beispiel, dass m verschie-
dene Aktionen für je n verschiedene Fälle implementiert
werden müssen, wie in der Matrix in Abbildung 2
dargestellt. Die strukturierte Programmierung löst dieses
Problem durch Fallunterscheidungen, die OO-
Programmierung durch Ableitung von einer virtuellen
Basisklasse. Beim strukturierten Ansatz werden zu-
nächst die Fälle jeder Zeile der Matrix über eine Fall-
unterscheidung notationell zusammengeführt (etwa zu
einer Prozedur), was jedoch meist nicht zu einer ge-
schlossenen Modulstruktur führt, da die verschiedenen
Aktionen auf dieselben Daten zugreifen. Der OO-
Ansatz fasst orthogonal dazu jede Spalte der Matrix zu
einer Klasse zusammen, die häufig den Charakter eines
526
eigenständiges Moduls hat und natürlich wesentlich
bessere Kohäsion aufweist als die strukturierte Imple-
mentierung. Im Idealfall besteht die Außensicht der
Klassenstruktur nur aus der Basisklasse, was die Zahl
der möglichen Außenbeziehungen drastisch reduziert.
n Fälle/Objekte
m Aktionen /
Methoden
Aktion
Klasse
Abbildung 2: Ableitung von einer Basisklasse vs. Fall-
unterscheidungen
Betrachten wir die fünf klassischen Eigenschaften der
Objektorientierung, nämlich Datenkapselung, Ver-
erbung, dynamisches Binden, Klassen und Polymor-
phismus, und ihre Beziehung zur Lokalität. (Weitere
Kriterien wie dynamische Speicherbereinigung und
Mehrfachvererbung werden oft vorgeschlagen, treffen
aber auf anerkannte OO-Sprachen teilweise nicht zu.
Auch ihr Beitrag zur Lokalität ist unbestreitbar.)
3.1 Datenkapselung
Bei der Behandlung gekapselter Daten kann alles
außerhalb der Kapselung außer Betracht bleiben. Umge-
kehrt braucht bei der Verwendung einer gekapselten
Datenstruktur nur deren öffentliche Schnittstelle be-
trachtet zu werden. Alles andere hat ausschließlich
lokale Bedeutung.
3.2 Vererbung
Vererbung erlaubt es, gemeinsame Eigenschaften meh-
rerer Klassen in einer Oberklasse zu konzentrieren,
anstatt sie mehrfach zu notieren (Abbildung 3). Mehr-
faches Notieren erfordert vom Leser zunächst die Kon-
trolle, ob wirklich völlige Übereinstimmung besteht; die
beiden identischen Teile sind nicht unabhängig, sondern
in enger, aber nicht lokaler Beziehung. Bei jeder Modi-
fikation lauert die Gefahr, dass Inkonsistenzen sich
einschleichen.
3.3 Dynamisches Binden
Während Vererbung erlaubt, Methoden einer Oberklasse
aus mehreren Unterklassen aufzurufen, erlaubt das
dynamische Binden (virtuelle Methoden), aus einer
Oberklasse Methoden mehrerer Unterklassen aufzuru-
fen. Dadurch kann gemeinsamer Kode auch dann in der
Oberklasse konzentriert werden, wenn er unterschiedli-
chen Kode in Unterklassen aufruft (siehe Abbildung 4).
Oberklasse:
Gemeinsame
Methode x
Unterklasse 1:
Separate
Methode y
Unterklasse 2:
Separate
Methode y
Aufruf
Abbildung 3: Vererbung: Aufruf einer Methode in
verschiedenen Unterklassen
Oberklasse:
Gemeinsame
Methode x
Unterklasse 1:
Separate
virtuelle
Methode y
Unterklasse 2:
Separate
virtuelle
Methode y
Aufruf
Abbildung 4: Dynamisches Binden: Aufruf von
Methoden verschiedener Unterklassen
3.4 Klassen
Außer Vererbung und Datenkapselung bringen Klassen
durch die Vereinigung von Typ- und Modulkonzept die
Möglichkeit, Daten und ausführbaren Kode zusammen
zu notieren. Der Gewinn an Proximität ist unübersehbar,
vor allem in Sprachen wie Java, wo auch Deklaration
und Implementierung in derselben Datei notiert werden.
3.5 Überladen (Polymorphismus)
Das Überladen von Methodennamen nach unterschied-
lichen Parametertypen bringt einen Gewinn an Lokalität
dadurch, dass solche unterschiedlichen Typen nicht
noch zusätzlich unterschiedliche Methodennamen erfor-
dern. Die Zahl der verschiedenen Bezeichner wird
dadurch reduziert. Allerdings scheint die Beziehung
zwischen Überladen und Lokalität eher lose. Der
Polymorphismus wird auch im Allgemeinen als weniger
wichtiges Kriterium der OO betrachtet.
4 WEITERE TECHNIKEN DER LOKALITÄT
Auch unabhängig von der Objektorientierung lassen
sich viele wichtige Standardtechniken der Programmie-
rung aus ihrem Lokalitätsgewinn heraus rechtfertigen.
4.1 Kleine Gültigkeitsbereiche
Wie bereits angedeutet, unterscheiden viele Program-
mierer nur drei Ebenen von Gültigkeitsbereichen für
527
Variablen: global, Klasse und Prozedur / Methode.
Weitere Ebenen innerhalb umfangreicher Klassen oder
längerer Prozeduren können die Lokalität (wie in
Abbildung 1 angedeutet) erheblich verbessern. Unter-
stützt wird dieses Vorgehen durch reichliches Verwen-
den von const (in C++) bzw. final (JAVA) usw.,
wodurch sich die Komplexität von Programmen stark
verringert. Hat der Leser die Initialisierung einer
konstanten Variable vor sich, so braucht er nicht in
Gedanken ihren Wertverlauf zu verfolgen, sondern weiß
sofort, dass sie diesen Wert über ihre gesamte Gültigkeit
hinweg behalten wird.
Es ist auffällig, dass etwa die Microsoft Foundation
Classes (MFC) die Technik der kleinen Gültigkeits-
bereiche sehr konsequent einsetzen, dagegen praktisch
kein const (außer Referenzen-const) verwenden,
obwohl es durchaus vergleichbare Gewinne an Über-
sicht und Sicherheit ermöglicht.
4.2 Beschränkung notationeller Distanzen
Bei der Notierung mehrdimensionaler Programm- oder
Datenstrukturen gibt es häufig verschiedene Möglich-
keiten, deren Lokalität ganz unterschiedlich ist.
Abbildung 5 zeigt ein einfaches Beispiel: In der ersten
Variante kann bei großen Tabellen die Entfernung
zwischen den zusammengehörigen Elementen beliebig
groß werden; Auslassungen und ähnliche Fehler sind
dadurch schwer feststellbar. Die zweite Variante ver-
meidet dieses Problem durch einfaches Vertauschen der
Dimensionen.
String laender[][] =
{
{ "AT", "BE", "DE",
"DK", ...
},
{ "Österreich",
"Belgien",
"Deutschland",
"Dänemark",
...
}
};
String laender[][] =
{
{ "AT", "Österreich" },
{ "BE", "Belgien" },
{ "DE", "Deutschland" },
{ "DK", "Dänemark" },
...
};
Abbildung 5: Unbeschränkte (oben) und beschränkte
(unten) Distanzen zwischen zusammengehörigen
Elementen
4.3 Sortierte Listen
Sortierte Listen sind nicht nur für den Rechner meist
effizienter zu handhaben als unsortierte, sondern redu-
zieren auch in Programmtexten die Anzahl der Zusam-
menhänge, die der Programmierer zu betrachten hat,
dramatisch: Nicht nur ist die Sortiertheit einer Liste
lokal feststellbar, in einer sortierten Liste kann
bekanntlich ein Element sehr schnell gefunden und
allein durch lokalen Vergleich das Vorhandensein von
Doubletten festgestellt oder ausgeschlossen werden. So
ist in Abbildung 6 nur in der rechten Variante sofort zu
erkennen, dass Griechenland aus Versehen zweimal ein-
getragen wurde. Ebenso wäre das Fehlen eines
bestimmten Elements leicht festzustellen. (Nebenbei
stellt die Verwendung einer Norm, ISO 3166, sicher,
dass nicht verschiedene Bezeichnungen für dasselbe
Land verwendet werden.)
char *EUStaat[] {
"DE″,
"PT″,
"GB″,
"AT",
"GR",
"FR",
"ES",
"BE",
"NL",
"LU",
"DK",
"IE",
"NO",
"IT",
"GR",
"FI",
};
char *EUStaat[] {
"AT",
"BE",
"DE",
"DK",
"ES",
"FI",
"FR",
"GB",
"GR",
"GR",
"IE",
"IT",
"LU"
"NL"
"NO"
"PT"
};
Abbildung 6: Unsortierte und sortierte Liste
4.4 Zusicherungen (Assertionen)
Ebenso lokalitätserhöhend wirkt die bekannte Technik
der Zusicherungen: Durch Prüfen von Konsistenzbedin-
gungen im Programm machen sich Fehler dort bemerk-
bar, wo sie begangen wurden, und nicht viele Anwei-
sungen später. Außerdem lässt sich dem Leser des
Programms durch eine Zusicherung eine Konsistenzbe-
dingung vermitteln, die an ganz anderer Stelle (oder an
vielen Stellen) gesichert wurde und die er ohne die
Zusicherung erst zusammensuchen müsste.
Auch wenn Zusicherungen durch ihre dynamische Aus-
wertung dem Problem der Fallabdeckung unterliegen
und infolgedessen nur unvollständige Aussagen liefern,
sind sie in ihrer Aussagekraft bloßen Programmkom-
mentaren überlegen (die natürlich auch ihre Berechti-
gung haben).
4.5 Präprozessor
Die textuelle Vorbearbeitung durch den Präprozessor in
C und C++ ist viel gescholten worden und hat auch in
Java keinen Eingang gefunden, vielleicht vor allem
wegen der bedingten Kompilierung (#if und #if-
def). Die Definition von Makros kann jedoch durchaus
zu einem Gewinn an Übersichtlichkeit und Program-
miersicherheit führen.
Abbildung 7 zeigt das Beispiel einer Tabelle von C++-
Schlüsselwörtern, die zur Sicherung gegen Tippfehler
als Stringkonstanten deklariert werden. Durch ein
528
Präprozessormakro wird die Notwendigkeit vermieden,
Name und Wert der Konstanten getrennt aufzuschrei-
ben, was die Möglichkeit von Schreibfehlern mit sich
bringen würde. Wem das weit hergeholt erscheint, der
sei an eine Version des Textprogramms Word für
Windows erinnert, die anstelle des RTF-Schlüsselwortes
"dobypage" die Variante "dopypage" verwendete!
#define def_schluessel( wort ) \
const char schl_##wort[] = #wort
def_schluessel( bool );
def_schluessel( char );
def_schluessel( do );
def_schluessel( false );
def_schluessel( float );
def_schluessel( for );
const char schl_bool [] = "bool" ;
const char schl_char [] = "char" ;
const char schl_do [] = "do" ;
const char schl_false [] = "false" ;
const char schl_float [] = "float" ;
const char schl_for [] = "for" ;
Abbildung 7: Vermeidung einer Doppelaufschreibung
durch Präprozessor: Quelltext (oben) und Ergebnis
5 BEDEUTUNG DER LOKALITÄT IN DER
PROGRAMMIERPRAXIS
Dass der OO-Ansatz und viele Standard-Ingenieurs-
techniken auf die Erhöhung der Lokalität in Program-
men ausgerichtet sind, dürfte nach dem bisher Gesagten
unstrittig sein. Aber auch umgekehrt kann das Streben
nach hoher Lokalität Programmentwurf und Kodierung
positiv beeinflussen, und zwar auf zwei Arten:
Unabhängig von der semantischen Qualität des
Entwurfs erleichtert die Lokalität das Verständnis,
sowohl während das Programm entsteht als auch
später.
Hindernisse bei der Verbesserung der Lokalität
können als wertvolle Hinweise auf Mängel des
Entwurfs aufgefasst werden.
Die Technik, bei Programmentwurf und Kodierung ein
Maximum an Lokalität anzustreben, führt zwar nicht
zwingend zu guter Modulkohäsion oder überhaupt zu
einem qualitativ hochwertigen Ergebnis. Sie besitzt
jedoch zwei große Vorteile: Sie ist einfach zu vermitteln
und anzuwenden, und sie führt kaum je zu einer
Verschlechterung des Entwurfs, selbst wenn sie nur
unvollkommen beherrscht wird.
Da aufgrund des derzeitigen Mangels an EDV-Fach-
kräften nicht überall, wo es wünschenswert wäre, ein
Diplominformatiker eingesetzt werden kann, werden
solche Techniken zunehmend wichtiger. Damit soll
keinem Klassendenken das Wort geredet, sondern im
Gegenteil die Wichtigkeit des ständigen Lernens wäh-
rend und an der laufenden Tätigkeit betont werden.
Als Anwendungsbeispiele seien das Refactoring und die
Vermittlung von Standardtechniken genannt.
5.1 Refactoring
Beim Refactoring alten Programmkodes, das beim Be-
mühen, solchen Kode wartbar zu halten, immer mehr an
Bedeutung gewinnt (vgl. [13]), ist die „Lokalitätsbrille“
eine große Hilfe, weil sie selbst dann Verbesserungen
ermöglicht, wenn das Verständnis des Kodes unvoll-
ständig ist. Zwar sind solche Verbesserungen im Allge-
meinen einem vollständigen OO-Neuentwurf unterlegen
(vgl. [6]). Refactoring wird jedoch üblicherweise dort
eingesetzt, wo ein solcher Neuentwurf aus Zeit- oder
sonstigen Kostengründen nicht möglich ist.
Bereits rein formale Lokalitätsverbesserungen, im ein-
fachsten Fall durch kleinere Gültigkeitsbereiche für
Variablen, können inhaltliche Strukturen im Kode deut-
licher hervortreten lassen und damit Hinweise für echte
Restrukturierung geben. Solche Verbesserungen lassen
sich in der Einsetzbarkeit mit semantikerhaltenden
Refactoring-Techniken vergleichen, die ebenfalls einen
sicheren Einsatz auch ohne globales Verständnis des
Ausgangskodes gestatten (s. [13] mit Verweis auf [11]).
5.2 Standardtechniken
Das Erkennen des Lokalitätsgewinns an Standardtech-
niken macht diese nicht nur für Anfänger leichter
vermittelbar, sondern erhöht auch die Motivation, solche
Techniken zu verwenden, da rein arbeitsökonomische
Erwägungen dafür sprechen. Eine solche Motivation ist
zwar der durch inhaltliches Verständnis unterlegen, führt
aber zumindest dazu, dass eine Technik im geeigneten
Fall eingesetzt wird, so dass weitere Erfahrungen dann
auch zu tieferem Verständnis führen. Wenn zum
Beispiel ein Programmieranfänger das Konzept von
Klassen- oder Schleifeninvarianzbedingungen nicht
sofort erfassen kann, jedoch aufgrund erster positiver
Erfahrungen Zusicherungen einsetzt, hat er bessere
Chancen, sich das volle Verständnis mit der Zeit zu
erwerben.
6 AUSBLICK: EINE PROXIMITÄTSMETRIK
Kopplung und Kohäsion eignen sich gut als Grundlage
für Softwaremetriken (vgl. [1]). Aber auch bestimmte
Programmeigenschaften, die großen Einfluss auf die
Proximität haben, sind leicht zahlenmäßig messbar und
können zur Bewertung und Verbesserung von Program-
men herangezogen werden. In [4] hat der Verfasser
Ansätze zu einer einfachen Proximitätsmetrik gegeben,
die lediglich auf der Größe der Gültigkeitsbereiche von
Identifikatoren beruht und sich auf die Überlegungen
am Ende von Abschnitt 2 stützt. Obwohl noch unklar
ist, inwieweit eine solche Metrik absolute Aussagen
über die Qualität von Programmen geben kann, erlaubt
sie jedenfalls Vergleiche zwischen verschiedenen Im-
plementierungen desselben Algorithmus und kann daher
insbesondere dem weniger erfahrenen Programmierer
bei einer Änderung Hinweise geben, wie sich diese auf
die Lesbarkeit ausgewirkt hat.
Ein solches Hilfsmittel kann natürlich fehlende Erfah-
rung nicht ersetzen, jedoch beim Erwerb von Erfahrung
Irrwege vermeiden helfen. Insofern ist es auf derselben
Ebene einzustufen wie Hilfsprogramme zur orthogra-
529
fischen und grammatikalischen Überprüfung von
Texten als Ersatz für die vielfach fehlenden Kenntnisse
auf diesen Gebieten. Da die Programmierung ein
deutlich formalerer Gegenstand ist als natürlichspra-
chige Texte, wird man hier sogar auf größeren Erfolg
beim Einsatz formaler Werkzeuge hoffen können.
SCHRIFTTUM
[1] Lionel C. Briand, John W. Daly, Jürgen K. Wüst:
A unified framework for coupling measurement in
object-oriented systems. IEEE Tr. on Software
Eng., Jan/Feb. 1999 (25) 1, 91–121.
[2] M. Brough: A Glossary of Y+ and Y++ terms.
Department of Computer Science Technical Report
TR95-09 (revised 1998).
http://www.keele.ac.uk/depts/cs/Staff/
Homes/Mdb3/papers/gloss.htm
[3] R. Fößmeier: Konstanter als „const“. Objektspek-
trum 5/94, 83–84.
[4] R. Fößmeier: Ansätze zu einem Lokalitätsmaß für
Rechnerprogramme. In: Europäische Kommunika-
tionskybernetik heute und morgen. 19–26. Mün-
chen, KoPäd, 1998.
[5] H.-J. Hofmann: Software-Zuverlässigkeit. VDI-
Verlag, 1993. http://www.fh-fulda.de/
medoc/konvert/vdi/
[6] Eliezer Kantorowitz; Algorithm simplification
through object orientation. Software—practice and
experience, vol. 27(2), February 1997, 173–183.
[7] S. Lehrl, H. G. Frank: Zur humangenetischen
Erklärung der Kurzzeitspeicherkapazität. Psycho-
genetics of Intelligence, verlag modernes lernen,
Dortmund 1982, 171-181.
[8] S. Lehrl, B. Fischer: The basic parameters of hu-
man information processing: Their role in the
determination of intelligence. Person indiv. Diff.,
vol. 9, no. 5, 883-896, 1988.
[9] G. A. Miller: The magical number seven, plus or
minus two: Some limits on our capacity for
processing information. Psychol. Rev., vo. 63, 81–
97, 1956.
[10] Glenford J. Myers: Reliable software through com-
posite design. New York, Van Nostrand Reinhold,
1975.
[11] W. Opdyke: Refactoring object-oriented frame-
works. Dissertation, University of Illinois at
Urbana-Champaign, 1992. Zitiert nach Reißing
[13].
[12] Michael Philippsen, Bernhard Haumacher: Locality
optimization in JavaParty by means of static type
analysis. In: Proc. workshop on Java for high per-
formance network computing at EuroPar'98, South-
ampton, September 2–3, 1998.
[13] Ralf Reißing: Refactoring. Informatik-Spektrum
22, 210–211 (1999).
[14] Edward Yourdon, Larry L. Constantine: Structured
design: fundamentals of a discipline of computer
program and systems design. Englewood Cliffs:
Prentice-Hall, 1979.
530