Zusammenfassung

  • Parnas verglich eine Zerlegung nach Verarbeitungsschritten mit einer Zerlegung nach veränderlichen Entwurfsentscheidungen. Beide konnten dieselben Algorithmen und sogar dieselbe ausführbare Darstellung besitzen.
  • Eine andere Zeilenspeicherung oder Zeichenpackung betraf im ersten Entwurf sämtliche Module, im zweiten nur Line Storage. Eine neue Darstellung der Zirkularverschiebungen betraf drei Module gegenüber einem.
  • Information Hiding ist weder Geheimhaltung noch Verschlüsselung, Laufzeitisolation oder ein Synonym für Objektorientierung. Auch eine Schnittstelle kann zu viel verraten, und die Grenze garantiert keine höhere Geschwindigkeit.

Der interessante Test beginnt nach dem grünen Testlauf

KWIC steht für Key Word in Context. H. P. Luhn veröffentlichte 1960 ein maschinell erzeugtes Register, das Schlüsselwörter im Kontext eines Titels zeigte. Parnas übernahm ein kleines, verständliches Problem: Zeilen einlesen, ihre zyklischen Wortverschiebungen bilden, diese alphabetisch sortieren und ausgeben.

Sein Aufsatz von 1972 sagt ausdrücklich, dass beide Entwürfe funktionieren. Sie können Datenrepräsentationen und Algorithmen teilen und nach der Montage sogar für die Maschine identisch sein. Der Unterschied liegt in den Darstellungen, die Menschen zum Ändern, Dokumentieren und Verstehen benutzen.

Eine heutige Veranschaulichung würde daher zunächst identische Ausgaben nachweisen. Danach würde sie eine Speicherentscheidung ersetzen und erfassen, welche Module, Tests und Verantwortlichen ihr Wissen ändern müssen. Das wäre ein Erklärungsmodell, keine Behauptung über ein historisches Testsystem.

Der erste Schnitt folgte dem Ablauf

Die konventionelle Zerlegung bestand aus Input, Circular Shift, Alphabetizing, Output und Master Control. Die Aufgaben waren getrennt, doch ihre Schnittstellen enthielten Speicherformate, gemeinsame Arrays, Indizes, Zeiger und Aufrufkonventionen. Input packte vier Zeichen in ein Maschinenwort; spätere Schritte kannten die Form der vorher erzeugten Tabellen.

Der Kontrollfluss war aufgeteilt, das Wissen über veränderliche Repräsentationen hingegen verteilt.

Die zweite Zerlegung ordnete Zuständigkeiten nach Entscheidungen. Line Storage besaß die interne Zeilendarstellung und bot Operationen für Zeichen, Wörter und Zeilen. Circular Shifter vermittelte eine Menge verschobener Zeilen, ohne offenzulegen, ob sie gespeichert, indiziert oder bei Bedarf berechnet wurden. Alphabetizer besaß die Sortierstrategie; Input und Output nutzten diese Dienste.

Ein module war dabei eine Verantwortungszuweisung, kein subroutine. Ein Modul kann mehrere Routinen enthalten; der montierte Code kann Beiträge mehrerer Module vereinen. Klasse, Paket, Prozess oder Team sind mögliche Träger, aber kein automatischer Beweis für die richtige Wissensgrenze.

Fünf Änderungen machten die Differenz messbar

Ein neues Eingabeformat blieb in beiden Entwürfen innerhalb von Input. Die konventionelle Lösung war nicht in jedem Punkt schlechter.

Sollten jedoch nicht mehr alle Zeilen im Hauptspeicher liegen, musste sich im ersten Entwurf jedes Modul ändern, weil alle das gemeinsame Format kannten. Im zweiten kannte nur Line Storage diese Politik. Dasselbe galt für die Entscheidung, vier Zeichen in ein Wort zu packen.

Wurden Zirkularverschiebungen nicht mehr als Index, sondern vollständig gespeichert oder erst auf Anfrage berechnet, waren im ersten Entwurf Circular Shift, Alphabetizer und Output betroffen. Im zweiten blieb die Änderung in Circular Shifter.

Auch der Zeitpunkt der Sortierung konnte wechseln: einmal vollständig, bei Bedarf schrittweise oder über die Erzeugungszeit verteilt. Der erste Output erwartete einen fertigen Index. In der zweiten Lösung konnten Nutzer nicht erkennen, wann Alphabetizer sortierte.

Das Wissen verschwindet nicht. Es erhält einen Eigentümer; alle anderen verlieren die Berechtigung, ihre Programme auf das Detail zu stützen.

Eine Schnittstelle kann immer noch zu viel wissen lassen

Parnas kritisierte seine zweite Lösung selbst. Circular Shifter legte die Reihenfolge der Verschiebungen fest: frühere Eingabezeilen zuerst, innerhalb einer Zeile das Original vor den Rotationen. Die Nutzer brauchten diese Zusage nicht. Sie verhinderte eine Implementierung, die Verschiebungen bereits alphabetisch erzeugte.

Der Aufsatz nennt dies einen Entwurfsfehler. Die Berechnungsmethode war verborgen, aber eine zufällige Ordnung öffentlich geworden. Private Felder und Zugriffsmethoden reichen nicht, wenn Rückgabeformen, Iterationsreihenfolge, Zeitgarantien oder Fehlerklassen die Volatilität kopieren.

Kein Sicherheitsbegriff und kein Leistungsversprechen

Das „Hiding“ bezeichnet keine Autorisierung, Verschlüsselung, Sandbox oder Prozessgrenze. Ein Geheimnis kann sein Schema im gesamten System verbreiten; eine öffentliche Entscheidung kann hinter einer Programmierschnittstelle lokalisiert bleiben.

Information Hiding ist auch kein anderer Name für Objektorientierung. Abstrakte Datentypen, Klassen und Kapselung können helfen, aber ebenso Persistenzdetails oder instabile Kategorien offenlegen. Kohäsion und Kopplung sind nützliches späteres Vokabular; sie ersetzen nicht die Benennung der Entscheidung.

Kompilierungsabhängigkeit und Wissensabhängigkeit sind verschieden. Ein Client kann neu gebaut werden, ohne semantisch geändert zu werden. Getrennt deploybare Dienste können dagegen dieselbe ungeschriebene Ordnung voraussetzen.

Auch Leistung folgt nicht automatisch. Parnas warnte, dass viele aufwendige Prozeduraufrufe den zweiten Entwurf verlangsamen könnten, und skizzierte Codeeinfügung oder spezialisierte Übergaben. Eine gute Wissensgrenze hebt Implementierungsarbeit nicht auf.

Das Lehrbeispiel brauchte selbst Korrektur

Später stellte Parnas fest, dass sein KWIC weiterhin alle Module wissen ließ, eine Zeichenkette sei eine Folge von Zeichen. Diese gemeinsame Annahme erschwerte eine kompakte Ganzzahldarstellung häufig verwendeter Strings. Selbst das kanonische Beispiel hatte nicht alle veränderlichen Entscheidungen beim ersten Versuch erkannt.

Die Entwicklung war zudem gemeinschaftlich. Der Text von 1971 behandelte Verbindungen als Annahmen zwischen Modulen. 1976 erweiterte das Konzept der Programmfamilien den Horizont auf verwandte Versionen. 1985 unterschieden Parnas, Paul C. Clements und David M. Weiss gemeinsam Modul-, Uses- und Prozessstruktur und beschrieben einen Modulführer für Wartende.

Spätere Architekturforschung verglich KWIC mit gemeinsamen Daten, Pipes und Filtern, Ereignissen und weiteren Stilen. Diese Arbeiten gehören nicht rückwirkend in den Aufsatz von 1972. Dessen langlebiges Verfahren bleibt: sichtbares Verhalten konstant halten, eine Entscheidung verändern und verfolgen, wie weit die Pflicht zum Wissen reicht.

Quellen