Montag, 20. Oktober 2014

Ein allgemeines Modell für Software-Systeme

1. Der System-Begriff

Zahlreiche Prinzipien handeln von Software als System. Sie beziehen sich auf Begriffe oder Konzepte, die nur dann nützlich sind, wenn man Software als System begreift. Dies ist kein Zufall. Die Erstellung von Software folgt einer jahrhundertelangen Historie der Technologie, und für viele Technologien hat sich eine systemartige Konstruktion und Handhabung als außerordentlich hilfreich erwiesen. Wächst eine Technologie über ein gewisses Maß hinaus an, so scheint eine Behandlung der Technologie als System eine für den Menschen naheliegende Möglichkeit zu sein, nicht die Kontrolle über die Technologie zu verlieren und ihren Nutzen aufrechterhalten oder steigern zu können.

Im zwanzigsten Jahrhundert wurde mit der allgemeinen Systemtheorie ein Rahmenwerk geschaffen, das die gelebte Praxis mit einem theoretischen Fundament untermauerte. Zudem erwies sich der System-Begriff als universal: Er war in der Lage, zahlreiche Phänomene der Natur, des menschlichen Zusammenlebens und der Technologie in einer einzigen Sichtweise zusammenzuführen. Dieser interdisziplinäre Ansatz bereicherte wiederum die Sicht auf technologische Zusammenhänge, da Erkenntnisse bspw. aus dem Bereich der Natur wiederum auf technologische Systeme übertragen werden konnten.

Wir können also feststellen, dass die Betrachtung von Software als System
  • einer langen Historie der Technologie-Handhabung folgt
  • auf einem ausgearbeiteten theoretischen Modell beruht
  • der Art und Weise, wie der Mensch mit seiner Umwelt interagiert, entgegen kommt.

2. Ein Modell für Software-Systeme fehlt bislang

Bislang wurde allerdings noch kein zufriedenstellender Versuch unternommen, den System-Begriff, wie er im Rahmen der allgemeinen Systemtheorie entwickelt wurde, um die Spezifika von Software-Systemen anzureichern. Dies führt in der Forschung dazu, dass unterschiedliche Autoren jeweils unterschiedliche System-Modelle für Software voraussetzen und somit auch zu unterschiedlichen Forschungs-Ergebnissen gelangen. 

Im Kontext der Behandlung von Prinzipien aus dem Bereich der Softwaretechnik stellt sich zudem ein grundsätzliches Problem: Da die Prinzipien einen Gültigkeitsanspruch haben, der über konkrete Werkzeuge (wie z. B. Programmiersprachen, Modellierungsumgebungen usw.) hinaus geht, sollte ihre Formulierung und Beschreibung weitgehend unabhängig von der Terminologie konkreter Werkzeuge erfolgen. Zugleich muss jedoch sichergestellt sein, dass auch die Anwendung eines Prinzips auf eine konkrete Technologie intuitiv und frei von Missverständnissen erfolgen kann.

Ein Beispiel für diese Problematik ist das Konzept des Pakets, das in zahlreichen Programmiersprachen zur Verfügung steht. Ein Paket stellt in erster Linie einen Namensraum dar, der zur Gruppierung der enthaltenen Elemente sowie der Vermeidung von Namenskonflikten dient. In einigen Programmier- und Modellierungssprachen werden Pakete als package bezeichnet, in anderen als namespace. Wieder andere Sprachen stellen kein explizites Paket-Kontrukt zur Verfügung, aber in der Praxis hat sich die Verwendung von Namens-Präfixen der Art <praefix>_modulname im Sinne des Paket-Konzepts etabliert. Gelegentlich trifft man auch auf eine leicht missbräuchliche Verwendung anderer Konstrukte, die im Wesentlichen auf eine Trennung von Namensräumen abzielt, wie z. B. die Nutzung von struct in C.

Um die verschiedenen zur Behandlung von Prinzipien relevanten Eigenschaften von Software-Systemen in einer einheitlichen Terminologie behandeln zu können, stelle ich daher in diesem Blogartikel ein allgemeines Modell für Software-Systeme vor, das im Wesentlichen auf zwei Fundamenten beruht:
  • In seinem Werk "Allgemeine Technologie: Eine Systemtheorie der Technik" [Ropohl1979/2009] stellt der Philosoph Günter Ropohl ein auf der allgemeinen Systemtheorie beruhendes Modell für technische Systeme vor, das auf den drei Grundkonzepten Funktion, Struktur und Hierarchie basiert.
  • Im Rahmen seiner wissenschaftlichen Grundlegung der Softwaretechnik [Wang2007] präsentiert Y. Wang eine formale Beschreibung abstrakter Systeme, aus der er die hierarchische Zusammensetzung von Software-Systemen ableitet. Auf dieser Grundlage kann das Grundkonzept der Hierarchie für Software-Systeme konkretisiert werden.
Diesen Betrachtungen werde ich ein viertes Grundkonzept hinzufügen, das Software-Systeme von allgemeinen technischen Systemen abgrenzt und das für zahlreiche Aspekte von softwarebezogenen Prinzipien hilfreich ist, nämlich die besondere Form der Repräsentation von Software-Systemen.

3. Die vier Grundkonzepte von Software-Systemen

Bereits Ende der 70er Jahre stellte der Günter Ropohl ein allgemeines System-Modell für Technik auf, das sich hervoragend als Grundlage für eine Anpassung auf Software-Systeme nutzen lässt. Ropohl unterscheidet drei Sichtweisen, die er das funktionale Konzept, das strukturale Konzept und das hierarchische Konzept nennt. Diese drei Systemaspekte übernehme ich weitgehend unverändert, spreche aber der Kürze halber von Funktion, Struktur und Hierarchie. Der Aspekt der Hierarchie lässt sich für Software-Syteme etwas präzisieren, da klar benannt werden kann und sollte, welche Elemente auf vierschiedenen Hierarchie-Ebenen vorkommen können. Zudem füge ich einen vierten Aspekt hinzu, den ich Repräsentation nenne. Dies trägt dem Sachverhalt Rechnung, dass für Software-Systeme (im Gegensatz zu einem allgemeinen Modell für Technik-Systeme, wie es Ropohl formuliert hat) bekannt ist, dass es aus bestimmten Repräsentationsformen wie z. B. Programmtext besteht. Es ergibt sich das folgende Bild:
Diese vier Grundkonzepte werde ich in den folgenden Abschnitten ausführlich erläutern. 


3.1. Funktion

Jedes Software-System erfüllt eine oder zahlreiche Funktionen, und es sind gerade diese Funktionen und der durch sie herbeigeführte Nutzen für den Menschen, die dem System seinen Existenzgrund verleihen. Die funktionale Betrachtung von Systemen folgt meist einem Blackbox-Konzept, d. h. die Funktion kann von außen beobachtet und beschrieben werden, ohne dass die innere Struktur des Systems für diese Betrachtung relevant ist. Für eine Blackbox-Beschreibung wäre es ausreichend, die Eingaben (Inputs) und Ausgaben (Outputs) des Systems zu beschreiben.

In seinem allgemeinen Modell technischer Systeme erlaubt Ropohl (über die Input/Output-Beschreibung hinaus) die Beschreibung innerer Zustände des Systems, macht jedoch keine näheren Angaben darüber, wie diese Zustände repräsentiert sind und wie Zuständsänderungen herbeigeführt werden können. Für Software-Systeme kann dies etwas präziser modelliert werden:
  • Zum einen werden die Zustände eines Software-Systems im Wesentlichen durch seine internen Daten-Objekte bestimmt. Wir können also an Stelle von Zuständen präziser von Daten sprechen.
  • Diese Daten werden vom Software-System in irgendeiner Weise verwendet, um einzelne Funktionen zu realisieren. Diese Verwendung von Daten zur Herbeiführung einer Funktion wird in der Modellbildung von Software-Systemen (z. B. im Bereich der Function Point-Analyse [Abran1999]) oftmals in Form funktionaler Prozesse modelliert.
Somit ergibt sich für das funktionale Konzept von Software-Systemen das folgende Gesamtbild:
  • Jedes nichttriviale System nimmt zur Ausübung seiner Funktion Eingaben (Inputs) entgegen.
  • Ggf. abhängig vom Zustand des Systems (also von der Ausprägung intern verwalteter Daten) besteht die Funktion des Systems darin, dass es ein klar definiertes Ausgabeverhalten (verkürzt: Outputs) zeigt.
  • Die Entgegennahme von Inputs, die interne Verwaltung von Daten und die Erzeugung von Outputs wird von funktionalen Prozessen übernommen.
Es ist erwähnenswert, dass diese Modellbildung noch nicht mit der Betrachtung konkreter Strukturen einhergeht (siehe nächster Abschnitt). Ein funktionaler Prozess kann ebenso wie der Zustand eines Systems rein logisch (also z. B. bereits im Rahmen der Anforderungs-Spezifikation) betrachtet werden. Letztlich wird im Software-System ein funktionaler Prozess jedoch ebenso wie sein Zustand durch eine Anzahl struktureller Elemente repräsentiert, welche eine ausführbare Verhaltensbeschreibung sowie eine konkrete Beschreibung der Daten-Objekte enthalten. An dieser Stelle ergibt sich der Schnittpunkt zwischen Funktion und Struktur.


3.2. Struktur

Die Struktur entspricht dem am häufigsten verwendeten intuitiven System-Begriff, auch in Bezug auf Software-Systeme. Die Struktur eines Software-Systems wird von seinen Elementen und deren Relationen gebildet, wobei zunächst offenbleibt, um welche Art von Elementen und Relationen es sich handelt. In Software-Systemen finden sich zahlreiche Element-Typen, die auf definierte Weise miteinander interagieren und daher mittels eines einfachen Modells dieser Art beschrieben werden können.

Im Rahmen einer strukturellen Betrachtung werden meist nur gleichartige oder doch zumindest nur bestimmte Elemente miteinander in Beziehung gesetzt. Beispielsweise beschreibt ein Komponentendiagramm die für den betrachteten Systemausschnitt relevanten Komponenten und ihre Schnittstellen sowie die Nutzungs-Relationen zwischen den Komponenten, blendet aber die Ebene der Pakete oder der Klassen aus. Ebenso zeigt ein Klassendiagramm die Klassen und ihre Relationen, blendet aber die konkrete Implementierung von Methoden aus. Dieser für Strukturbetrachtungen typische Mangel der Fokussierung auf eine eingeschränkte Menge von Elementen wird durch das Konzept der Hierarchie aufgefangen.


3.3. Hierarchie

3.3.1. Allgemeine Systemhierarchie

Wie jedes andere technologische System ist ein Software-System hierarchisch aufgebaut. In der allgemeinen Terminologie spricht Ropohl von Systemen und Subsystemen, d. h. diejenigen Teile, die uns im Struktur-Konzept als "Elemente" begegnet sind, können im hierarchischen Konzept ihrerseits Systeme sein, die wiederum Elemente und Relationen der nächst tieferen Ebene enthalten usw. 

Im Kontext von Software-Systemen lassen sich die wichtigsten hierarchischen Ebenen vergleichsweise allgemein benennen. Ich schlage das folgende Modell vor, das auf einem etwas einfacheren Vorschlag in [Wang2007, S. 807] beruht:
Das Modell unterscheidet zwei Dimensionen:
  • Die logische Hierarchie ist diejenige Entwurfs-Dimension, die bei der Modellierung und Entwicklung von Software-Systemen meist im Vordergrund steht.
  • Die physische Hierarchie wurde eingeführt, um den Sachverhalt abbilden zu können, dass ein Software-System nicht als reines Konzept existiert, sondern in irgendeiner physischen Form auf ein Rechensystem transferiert und dort ausgeführt werden muss. Dieser Transfer der logischen Dimension in die physische ist mit eigenständigen Fragestellungen verbunden, die von einigen Prinzipien adressiert werden.
 Betrachten wir zunächst die physische Hierarchie:
  • Das System bildet die höchste Betrachtungs-Ebene und existiert zugleich physisch und logisch. In physischer Hinsicht wird es durch alle physischen Einheiten und zusätzlichen Artefakte gebildet, die in Form von Dateien oder anderen persistenten Informationsträgern auf einem Computer vorhanden sein müssen, um das System auf diesem Computer ausführen zu können.
  • Die physischen Einheiten sind die zentralen ausführbaren Bestandteile, aus denen ein System zusammengesetzt wird. Die Eigenschaften physischer Einheiten habe ich im Artikel Was ist eine physische Einheit? detailliert beschrieben. Physische Einheiten können andere physische Einheiten enthalten (z. B. können mehrere physische Einheiten in ein Archiv verpackt werden, das dann seinerseits eine physische Einheit ist).
  • Die Repräsentation des Systems existiert zugleich physisch und logisch. In physischer Hinsicht wird sie durch Dateien oder andere persistente Informationsträger gebildet. In logischer Hinsicht muss Software in irgendeiner textuellen oder modellartigen Form repräsentiert werden, welche 
    • das Verhalten der Software für Entwickler beschreibt
    • die Instruktionen der Software für das Rechensystem beschreibt.
Die Ebene der Repräsentation ist zugleich der Schnittpunkt der beiden Konzepte Hierarchie und Repräsentation. Das Konzept der Repräsentation wird im Abschnitt 3.4. noch ausführlich beschrieben.

Die logische Hierarchie ist tiefer und gestaltet sich wie folgt:

  • System: Siehe oben.
  • Subsystem: Die höchste Element-Ebene innerhalb eines Systems bezeichne ich als Subsystem (Alternativbegriff: Komponente). Subsysteme unterscheiden sich von Paketen durch eine klar definierte Schnittstelle sowie durch die Tatsache, dass sie potentiell ineinander verschachtelt werden können. Dies bedeutet, dass auf der Ebene der Subsysteme potentiell weitere Hierachie-Ebenen entstehen können. Beispielsweise kann die Schicht eines Schichtenmodells als ein Subsystem verstanden werden. Innerhalb dieser Schicht kann es weitere Zusammenfassungen geben, die ebenfalls als Subsysteme modelliert werden. Auf der Ebene von Programmiersprachen sind Subsysteme bis heute allerdings nur selten anzutreffen. Es handelt sich daher eher um ein Spezifikationskonzept, das in der nicht ausführbaren Repräsentation des System-Modells verwendet wird, beispielsweise in Form von Architekturdokumentation oder Komponentendiagrammen. In einigen technologischen Umgebungen fallen Subsysteme mit physischen Einheiten zusammen. Ein Beispiel hierfür sind Bundles im OSGi-Kontext.
  • Paket: Pakete ermöglichen eine Gruppierung der Elemente der Typ-Ebene und haben über die Gruppierung hinaus den hauptsächlichen Zweck der Vermeidung von Namenskonflikten. Im Gegensatz zu Subsystemen lassen sich Pakete nicht schachteln, auch wenn beispielsweise die Form der Paket-Spezifikation in Java den Anschein einer Hierarchie vermittelt. Jedoch sind auch in Java alle Pakete vollständig unabhängig voneinander und bilden daher keine echte Hierarchie. Die Paket-Ebene wird daher von der Subsystem-Ebene unterschieden, weil sie in vielen Programmiersprachen die höchste syntaktisch ausdrückbare Unterteilungsmöglichkeit des Systems ist. Modulsysteme wie Jigsaw könnten in Zukunft die Modellierung von Subsystemen auf der Programmiersprachen-Ebene ermöglichen und damit diese syntaktische Barriere nach oben verschieben.
  • Typ: In vielen Programmiersprachen bildet diese Ebene die zentrale Entwurfs-Ebene. Bedauerlicherweise existiert kein passender Oberbegriff, der diese Entwurfsebene für alle Programmiersprachen korrekt bezeichnet. Der Begriff "Typ" hat den Mangel, dass er im Kontext sogenannter "untypisierter Programmierspachen" scheinbar keinen Sinn ergibt. Andererseits ist mir keine Programmiersprache bekannt, in der tatsächlich keinerlei Typisierung anzutreffen ist. Selbst in Sprachen wie Smalltalk oder Lisp, die gemeinhin als "untypisiert" bezeichnet werden, findet zumindest eine Laufzeitüberprüfung der Typinformation statt. So können in Lisp z. B. Listen-Operationen nur auf Listen, nicht aber auf Atome angewandt werden. Alternative Begriffe wie "Modul" sind historisch oftmals anders belegt und bieten daher zu viel Spielraum für Missverständnisse. Nun zu den Eigenschaften von Typen:
    • Typen stehen im Rahmen dieses hierarchischen System-Modells für Elemente, die Funktionen enthalten. (Variablen sind in diesem Modell nicht enthalten, da sie keiner weiteren Hierarchisierung unterliegen.)
    • Typen erlauben eine Schnittstellen-Spezifikation, d. h. es können Implementierungs-Details im Sinne des Geheimnisprinzips verborgen werden. 
    • Typen können bis zu einem gewissen Grad "innere Typen" definieren und auf diese Weise eine Typ-interne Hierarchie bilden. (Dieser Sachverhalt ist nicht zu verwechseln mit der Komposition von Objekten, die unten in Abschnitt 3.3.2. besprochen wird.)
  • Funktion: Funktionen kommen in verschiedenen Erscheinungsformen vor: Als Toplevel-Funktionen in funktionalen Programmiersprachen, als Memberfunktionen in objektorientierten Programmiersprachen, als Prozeduren (ohne Rückgabewert) oder Funktionen (mit Rückgabewert) in strukturierten Programmiersprachen. Neben diesen Erscheinungsformen können sich Funktionen bei ihrem Aufruf hinsichtlich der Art der Parameterübergabe ("by value" vs. "by reference") unterscheiden.
  • Kontrollstrukturen: Als "elementare Kontrollstrukturen" (engl. basic control structures) bezeichnet [Wang2007] eine Reihe von Elementarbausteinen, aus denen die Körper von Funktionen aufgebaut werden können. Konkret sind dies: Sequenz, Verzweigung, Switch, While-Schleife, Repeat-Schleife, For-Schleife, Funktionsaufruf, Rekursion, Parallele Verarbeitung und Interrupt. Auf Details dieses Ansatzes werde ich in einem späteren Blogartikel eingehen.
  • Repräsentation: Siehe oben.

3.3.2. Vererbung und Komposition in der Objektorientierung

Neben der oben beschriebenen allgemeinen Hierarchie spielen weitere Formen der Hierarchisierung eine besondere Rolle für die Modellierung objektorientierter Systeme. Zum einen ist hier die Vererbungs-Hierarchie zu nennen, welche die naheliegende Hierarchisierungs-Form objektorientierter Systeme auf der Typ-Ebene darstellt. Zum anderen ist dies der Mechanismus der Komposition, d. h. die Bildung von Objektgeflechten im Software-System. Beide Modellierungsformen können ggf. gegen eine strenge Hierarchisierung verstoßen. Im Falle der Vererbung gilt dies jedoch nur für Sprachen, die eine Mehrfachvererbung unterstützen. Im Falle der Komposition entstehen im Falle eines Verstoßes Zyklen im Objektgeflecht.


3.4. Repräsentation

Die oben besprochenen Aspekte Funktion, Struktur und Hierarchie folgen der allgemeinen Modellbildung für technische Systeme, die in [Ropohl1979/2009] auf der Basis der allgemeinen Systemtheorie entwickelt wurde. Für Software-Systeme kann über diese Modellbildung hinaus auch noch diejenige Besonderheit in das System-Modell aufgenommen werden, die spezifisch für Software gegenüber andersartigen technologischen Systemen ("Hardware") ist. Diese Besonderheit ist die Eigenschaft von Software, Information zu sein.

Und zwar ist Software keine beliebige Information, sondern eine Verhaltensbeschreibung. Y. Wang spricht von einem "set of behavioural information" und führt aus: 
"Software ist sowohl eine Verhaltens-bezogene Information für Entwickler als auch eine Instruktions-bezogene Information für Computer." [Wang2007]
Ein Software-System im engeren Sinne wird somit durch seine ausführbare Systembeschreibung repräsentiert, welche zugleich auch die oben beschriebenen System-Aspekte der Funktion, Struktur und Hierarchie festlegt. Diese ausführbare Systembeschreibung wird ggf. von Dokumenten und Modellen zur Spezifikation und Dokumentation der Software begleitet, die z. T. nicht ausführbar sind.


Zusammenfassung

Software als System aufzufassen, bietet zahlreiche Vorteile. Zu diesen zählt eine lange Tradition in der Handhabung andersartiger technologische Systeme sowie ein ausgearbeitetes theoretisches Fundament in Gestalt der allgemeinen Systemtheorie. 
 
In diesem Artikel wurde ein allgemeines Modell für Software-Systeme vorgestellt, das sich aus vier Konzepten zusammensetzt, die untereinander diverse Schnittpunkte aufweisen. Diese vier Konzepte sind Funktion, Struktur, Hieararchie und Repräsentation:
  • Die Funktion stellt den eigentlichen Existenzgrund der Software dar und lässt sich auf der Grundlage von Inputs und Outputs beschreiben. Zur Herbeiführung dieser Funktionen greift ein Software-System auf funktionale Prozesse und eine interne Datenhaltung zurück.
  • Die Struktur ist ein sehr allgemeines Modell aus Elementen und deren Relationen.
  • Die Hierarchie spiegelt den Sachverhalt wider, dass die Elemente eines Systems ihrerseits Subsysteme darstellen können.
  • Die Repräsentation wurde schließlich - abweichend von allgemeinen technologischen Systemen - eingeführt, um den besonderen Charakter von Software erfassen zu können, der darin besteht, Information zu sein.
Mit diesem Modell steht uns nun ein Instrument zur Verfügung, um den Geltungsbereich verschiedener Prinzipien besser einordnen zu können. Ich werde daher in künftigen Blogartikeln immer wieder auf dieses Modell zurückkommen (und es ggf. weiter verfeinern).


Quellen

[Ropohl1979/2009] - Allgemeine Technologie: Eine Systemtheorie der Technik, Ropohl, Günter, 1. Auflage 1979 / 3. überarbeitete Auflage 2009 

[Wang2007]  - Software Engineering Foundations - A Software Science Perspective, Wang, Yingxu (2007)