Melden Sie sich hier an, um auf Kommentare und die Whitepaper-Datenbank zugreifen zu können.

Kein Log-In? Dann jetzt kostenlos registrieren.

Falls Sie Ihr Passwort vergessen haben, können Sie es hier per E-Mail anfordern.

Der Zugang zur Reseller Only!-Community ist registrierten Fachhändlern, Systemhäusern und Dienstleistern vorbehalten.

Registrieren Sie sich hier, um Zugang zu diesem Bereich zu beantragen. Die Freigabe Ihres Zugangs erfolgt nach Prüfung Ihrer Anmeldung durch die Redaktion.

05.02.2007

UML: Auch für Komplettsysteme geeignet

Wer die Unified Modeling Language (UML) zur Entwicklung kompletter Systeme einschließlich Hardware verwendet, muss auf einige Anpassungen der Notation achten.
Die für ein Türsystem benötigten Komponenten lassen sich in der UML durch Stereotypen zusätzlich klassifizieren (Angaben in spitzen Klammern). Auf diese Weise werden logische (gruppierende) Komponenten beziehungsweise Hard- und Softwarekomponenten spezifiziert.
Die für ein Türsystem benötigten Komponenten lassen sich in der UML durch Stereotypen zusätzlich klassifizieren (Angaben in spitzen Klammern). Auf diese Weise werden logische (gruppierende) Komponenten beziehungsweise Hard- und Softwarekomponenten spezifiziert.
Das Türsystem enthält die Softwarekomponente "Lokale Türsteuerung". Hier die in der UML notierten Use Cases der Komponente, wobei auch die Kommunikationspartner (zentrales Pult, Taster etc.) dargestellt sind.
Das Türsystem enthält die Softwarekomponente "Lokale Türsteuerung". Hier die in der UML notierten Use Cases der Komponente, wobei auch die Kommunikationspartner (zentrales Pult, Taster etc.) dargestellt sind.
Die Darstellung von Schnittstellen kann in der UML als Klasse mit dem Sterotyp "Interface" erfolgen. Eine Komponente, die einer anderen eine Schnittstelle zur Verfügung stellt, wird mit dieser über eine "Realize"-Beziehung verbunden, umgekehrt verwendet man eine "Use"-Verbindung. Über den Stereotyp "Delegate" werden die von Subkomponenten angebotenen Schnittstellen abgebildet.
Die Darstellung von Schnittstellen kann in der UML als Klasse mit dem Sterotyp "Interface" erfolgen. Eine Komponente, die einer anderen eine Schnittstelle zur Verfügung stellt, wird mit dieser über eine "Realize"-Beziehung verbunden, umgekehrt verwendet man eine "Use"-Verbindung. Über den Stereotyp "Delegate" werden die von Subkomponenten angebotenen Schnittstellen abgebildet.

Die UML gilt in der Softwareentwicklung seit einiger Zeit als gängiges Notationsmittel, um die Ergebnisse der Analyse- und Designphasen zu dokumentieren. Nun liegt die Frage nahe, ob und wie sich diese Notation auf die Systementwicklung übertragen lässt, zumal es viele Parallelen gibt: Die aus der Softwareentwicklung bekannten Workflows, Analyse, Architektur und Design finden sich auch im Systementwurf wieder, allerdings in etwas anderer Form. In beiden Disziplinen wird eine Zerlegung des Ganzen in kleinere, überschaubare Teile vorgenommen. Für die so gefundenen Komponenten müssen deren Aufgaben und Zusammenspiel festgelegt werden. Zu beachten sind sowohl statische als auch dynamische Aspekte, die die Struktur des Systems und den Ablauf der geforderten Funktionen definieren.

Fazit

Die UML kann als Notation für die Darstellung einer Systemarchitektur eingesetzt werden. Ein zentraler Bestandteil ist dabei die Stereotypisierung sowohl im Bereich der Komponentenbildung als auch für die Schnittstellenklassifizierung. Außerdem lassen sich Analysetechniken wie die Use-Case-Analyse in der Systemarchitektur für eine nähere Untersuchung der Systemkomponenten verwenden.

Literatur

• Buschmann, F.: Pattern-orientierte Software-Architektur, Addison-Wesley GmbH, 1998.

nQueins, S.; Rupp, C.: Profile helfen bei der Arbeit mit UML, www.computerwoche.de/ 572838.

nRupp, C.; Hruschka, P.: Agile Softwareentwicklung - für Embedded Real-Time Systeme mit der UML, Hanser, 2002.

nRupp, C.; Hahn, J.; Queins, S., u.a.: UML 2 glasklar, Hanser, 2005.

nStarke, G.: Effektive Software-Architekturen, Hanser, 2002.

Drei Aufgaben

Die Tätigkeiten eines Systemarchitekten bestehen im Wesentlichen aus drei übergeordneten Aufgabenbereichen:

Zunächst gilt es für die Strukturierung des Systems die Komponenten zu identifizieren. Dazu muss er das System in kleine, unabhängig voneinander realisierbare Einheiten zerlegen und diese in einem hierarchischen Baum darstellen.

Im zweiten Schritt muss er die Aufgaben der Komponenten festlegen. Sie werden als Nachrichten im Sequenzdiagramm notiert. Zusammengenommen müssen die Aufgaben die Anforderungen beziehungsweise gewünschten Funktionen eines Gesamtsystems erfüllen.

Schließlich geht es um die Schnittstellen. Da die Interaktionen zwischen den Komponenten schon im Sequenzdiagramm definiert wurden, sollte es nicht schwerfallen, die Schnittstellen und ihre Funktionen zu finden.

Mehr zum Thema

www.computerwoche.de/

568646: Domänenmodell erleichtert die Kommunikation;

1050899: Eclipse UML, ein guter Kompromiss.

Bei genauerer Betrachtung finden sich schnell die ersten Unterschiede zwischen der System- und der Softwarearchitektur. Zunächst einmal gibt es in der Systemarchitektur keine Artefakte oder Prozesse, die man auf eine Systemlandschaft verteilen muss. Es werden also keine Prozess- oder Verteilungssichten benötigt, wie man sie aus der reinen Softwarearchitektur kennt. Je nach Art der Systemzerlegung muss aber möglicherweise eine Gruppierung der Systemkomponenten zu räumlichen Komponenten (Schränke, Einsteckkarte etc.) vorgenommen werden.

Architekturunterschiede

Ein weiterer Unterschied zeigt sich in der Art der Komponenten, aus denen ein System besteht. In der Softwarearchitektur werden natürlich nur reine Softwarekomponenten benötigt. In der Systemarchitektur braucht man jedoch eine zusätzliche Möglichkeit, um Software- und Hardwarekomponenten unterscheiden zu können. Die Komponentenbildung unterliegt außerdem anderen Gesichtspunkten. So kann für die Zerlegung eines Systems ein wichtiges Kriterium die Beauftragung durch externe Lieferanten sein, was man bei der Softwarearchitektur eher selten findet. Ebenso lässt sich leicht erahnen, dass typische Muster aus der Softwarearchitektur wie das Schichtenmodell oder Pipes and Filter nicht ohne weiteres in die Systemarchitektur übertragen werden können.

Da sich die Unterschiede im Entwurf einer System- und Softwarearchitektur hauptsächlich auf Tätigkeiten beschränken, die erzeugten Ergebnisse sich in ihrer Art aber ähneln, stellt die UML auch für Systeme eine adäquate Möglichkeit dar, einen Großteil dieser Ergebnisse zu dokumentieren. Es geht nicht darum, bewährte Notationen der Hardwareentwicklung wie zum Beispiel Konstruktionszeichnungen abzulösen. Vielmehr bietet die UML in einigen Bereichen eine gewinnbringende Zusatzoption. Dies ist der Fall, wenn es um die Kommunikation der an der Systementwicklung beteiligten Teams geht, um die Nachvollziehbarkeit der Entwicklungsentscheidungen oder um einen leichteren Übergang zur Softwareentwicklung.

Start mit Use-Case-Analyse

Der Ausgangspunkt für ein auf der UML 2.0 basierendes Modell der Systemarchitektur ist die vollständige Systemanalyse, aus der die Anforderungen an das System bis zu einer gewissen Tiefe hervorgehen. Eine Technik hierfür ist die Use-Case-Analyse, mit der die funktionalen Anforderungen an ein System ermittelt und dokumentiert werden können. Dieser Ansatz schließt mit ein, dass die Use Cases (typische Interaktionen des Systems mit seiner Umwelt) durch Aktivitätsdiagramme oder, vor allem bei Realtime-Embedded-Systemen, durch Zustandsautomaten detailliert werden. Darüber hinaus bilden die nichtfunktionalen Anforderungen wie Zuverlässigkeit, Sicherheit oder die Einbettung des Systems in seine Umwelt eine wichtige Eingabe in die Systemarchitektur. Auch diese Aspekte werden in der Systemanalyse erhoben und dokumentiert.

In der Praxis wird man kaum eine vollständige Systemanalyse vor den ersten Architekturtätigkeiten erreichen. Normalerweise ergibt sich ein verzahnter Prozess zwischen einer groben Analyse, den ersten Architekturfestlegungen sowie einer Verfeinerung der Analyseergebnisse.

Die Strukturierung eines Systems ist nur eine von mehreren Tätigkeiten, die ein Architekt vorzunehmen hat. Eine zweite ist die Beschreibung der Komponenten innerhalb dieser Struktur, insbesondere die Beschreibung der Aufgaben der einzelnen Komponenten. Die Definition der Schnittstellen zwischen den Komponenten bildet den dritten wichtigen Aspekt in der Architektur. Das Ziel einer Architektur sowohl in der Software- als auch in der Hardwareentwicklung ist es, diejenigen Komponenten zu identifizieren, die losgelöst von ihrer Umgebung realisiert werden können.

Alle drei Tätigkeiten sind eng miteinander verbunden. Sie beeinflussen sich gegenseitig und liefern Input für die jeweils anderen Tätigkeiten. Aus diesem Grund werden die Tätigkeiten in der Systemarchitektur nicht wasserfallartig ausgeführt, sondern iterativ und eng verzahnt.

Iteratives Vorgehen

Um Komponenten zu identifizieren, wird das System nach und nach vollständig zerlegt und ein hierarchischer Baum von Komponenten erzeugt. Methoden hierfür sind das Top-down-, Bottom-up- und Middle-out-Vorgehen. Letzteres bedeutet, dass man Komponenten auf den mittleren Hierarchieebenen identifiziert und diese dann sowohl nach unten hin verfeinert als auch nach oben hin zusammenfasst. In der Praxis geht man selten streng nach einer Methode vor, sondern wechselt zwischen allen drei Verfahren.

Wird ein Punkt erreicht, an dem die weitere Aufteilung einer Komponente schwerfällt, sollte man zunächst ihre Aufgaben definieren. Dieses zusätzliche Wissen über die Komponente ist eine gute Grundlage für das weitere Vorgehen hinsichtlich ihrer Zerlegung. Gerade im Rahmen von Neuentwicklungen ist diese iterative Herangehensweise nützlich.

Die Sonderfälle

Bei der Erstellung einer Komponentenstruktur gilt es allerdings Einschränkungen zu berücksichtigen. So zum Beispiel, wenn Komponenten einem Zulieferer zugeordnet sind. In diesem Fall sollte man eine Komponente so bilden, dass sie nur die Bestandteile des Systems enthält, die von dem jeweiligen Zulieferer gefertigt werden können. Ein weiteres Kriterium bei der Strukturierung des Systems kann die räumliche Anordnung der Systemteile sein. Besteht das System zum Beispiel aus mehreren, voneinander getrennten Baugruppen, so können diese die erste Hierarchieebene in der Komponentenzerlegung bilden. Ferner kommen die aus der Softwarearchitektur bekannten Prinzipien für das Schneiden von Komponenten zum Tragen. Das sind zum Beispiel eine hohe Kohäsion, eine geringe Kopplung oder eine überschaubare Anzahl von Komponenten.

Bis zu welcher Ebene ein System zerlegt werden sollte, ist im Prinzip leicht zu beantworten: Es gilt, Komponenten zu finden, deren Umsetzung die Realisierung anderer Komponenten nicht mehr beeinflusst. Eine Ausnahme bilden hier natürlich die Schnittstellen der Komponenten.

Zur Darstellung der Systemkomponenten verwendet man als Notationsmittel die UML-Komponenten. Diese können durch die so genannten Stereotypen zusätzlich klassifiziert werden, die Angabe erfolgt in spitzen Klammern. So lässt sich beispielsweise die Unterscheidung zwischen logischen, das heißt gruppierenden Komponenten beziehungsweise Hard- und Softwarekomponenten über die Stereotypen <<logical>>, <<HW>> und <<SW>> abbilden, oder als weitere mögliche Unterscheidung <<HW-Elektronik>> und <<HW-Mechanik>>.

Komponenten und ihre Rollen

Nachdem die Komponenten identifiziert wurden, muss man sich Gedanken darüber machen, welche Rollen sie im zukünftigen System spielen werden. Daher beschäftigt sich die zweite Tätigkeit innerhalb der Systemarchitektur damit, die Aufgaben von Komponenten festzulegen. Bereits in der Systemanalyse, möglicherweise in Form von System-Use-Cases und deren Verfeinerungen, wurden die Anforderungen und gewünschten Funktionen des Systems erarbeitet. Nun geht es darum, diese Anforderungen auf die einzelnen Komponenten zu verteilen und damit auszudrücken, welche Aufgaben welche Komponenten übernehmen.

Die Zuweisung von Aufgaben lässt sich in Form eines Sequenzdiagramms notieren, was gleichzeitig eine "Plausibilitätskontrolle" der Zuteilung zur Folge hat. Als Kommunikationspartner erscheinen die an der Realisierung eines Use Case beteiligten Komponenten. Die Nachrichten in dem Sequenzdiagramm bilden dann die Aufgaben der Komponenten ab. Eine Nachricht kann entweder der Aufruf einer Operation sein (synchrone Nachricht) oder das Senden eines Signals/ Events (asynchrone Nachricht). In beiden Fällen ist die sendende Komponente dafür verantwortlich, die Nachricht zu erzeugen.

Zuordnung der Aufgaben

Ebenso muss die empfangende Komponente in irgendeiner Weise auf die Nachricht reagieren. Im Falle einer synchronen Nachricht muss der Sender zusätzlich auf die Antwort warten und diese verarbeiten. Für eine eindeutige Zuordnung der Aufgaben ist oft eine Verfeinerung etwa in Form der Aufteilung von Aktivitäten in einzelne Aktionen nötig. Bei der Entscheidung, welche Teilaufgabe in welcher Komponente realisiert werden soll, spielen die nichtfunktionalen Anforderungen wie Zuverlässigkeit, Zeitverhalten, Fehlertoleranz etc. eine wichtige Rolle.

Der nächste Teilschritt beschäftigt sich damit, aus den zuvor zugewiesenen Aufgaben die Anforderungen an die Komponenten zu bestimmen. Diese Tätigkeit entspricht einer konventionellen Analyse der einzelnen Komponenten, ähnlich wie in der Systemanalyse die Anforderungen an das Gesamtsystem erarbeitet wurden. Aus diesem Grund lassen sich auch die bekannten Analysemethoden wie Use Case und deren Detaillierungen heranziehen. Nur eben mit dem Unterschied, dass nun nicht das gesamte System, sondern eine Komponente im Mittelpunkt der Analyse steht. Demnach werden im Use-Case- Diagramm Komponenten-Use-Cases und als Systemgrenze die betrachtete Komponente auftauchen. Die Akteure werden durch die Nachbarkomponenten gebildet.

Bei der Use-Case-Analyse einer Komponente werden alle zuvor zugewiesenen Aufgaben betrachtet, diese eventuell zu neuen Use Cases zusammengefasst und die Use Cases weiter detailliert. Es gibt natürlich neben der Use-Case-Analyse auch die Möglichkeit, das (gewünschte) Verhalten einer Komponente durch einen Zustandsautomaten oder einfach durch natürlichsprachliche Anforderungen zu beschreiben.

Da die Komponenten in einem Gesamtsystem arbeiten, benötigt man Schnittstellen, über die Daten und Services ausgetauscht werden. Ziel dieser dritten Architekturtätigkeit ist es, genau diese Schnittstellen zwischen den Komponenten festzulegen. Prinzipiell unterscheidet man zwischen "angebotenen" (provided) und "benötigten" (required) Schnittstellen. Eine angebotene Schnittstelle stellt Dienste nach außen zur Verfügung, wohingegen eine benötigte Schnittstelle Dienste von außen in Anspruch nimmt. Diese Unterscheidung ist oft nicht einfach, da durch sie keine Aussagen über die Kommunikationsrichtung getroffen werden. Man sollte an dieser Stelle intuitiv vorgehen und das Anbieten von Diensten als angebotene Schnittstelle modellieren. Um die Schnittstellen zwischen den Komponenten zu finden, nutzt man die bereits beschriebenen Sequenzdiagramme, in denen die Interaktionen zwischen den Komponenten definiert sind.

Stereotypen für Schnittstellen

Prinzipiell sollte jede Komponente in der Komponentenhierarchie Schnittstellen besitzen. Wenn eine Komponente eine Schnittstelle anbietet, bedeutet dies nicht zwingend, dass diese realisiert, also zum Beispiel ein Stück Code implementiert werden muss. Nehmen wir als Beispiel dafür die Schnittstelle einer Komponente auf unterster Ebene. Genau diese Schnittstelle möchten wir auch in der darüber liegenden Komponente sichtbar machen. In diesem Fall können Schnittstellen nach oben delegiert werden. Das bedeutet, eine Komponente stellt die Schnittstelle ihrer Subkomponente zur Verfügung, hat aber keinen Realisierungsanteil für diese Schnittstelle. Anders sieht es aus, wenn eine Komponente mehrere Schnittstellen ihrer Subkomponenten zusammenfasst, also eine Art Fassade bildet. Hier muss auch die darüber liegende Komponente einen Teil der Realisierung übernehmen.

Die UML bietet unterschiedliche Darstellungsmöglichkeiten für Schnittstellen. Eine davon sind die Interface-Klassen. Hier legt man eine Klasse mit dem Stereotyp <<interface>> an. Die Komponente, die dieses Interface zur Verfügung stellt, wird anschließend über eine <<realize>>-Beziehung verbunden, die verwendende Komponente über eine <<use>>-Beziehung mit dieser Klasse. Eine abkürzende Schreibweise ist die Notation "Ball & Socket". Hier werden die angebotene Schnittstelle über eine Kugel (den so genannten Lollipop) und die benötigte Schnittstelle über einen Halbkreis dargestellt.

Relationen delegieren

Das Delegieren von Schnittstellen wird in der UML-Notation über eine Abhängigkeitsrelation mit dem Stereotyp <<delegate>> dargestellt. Diese Beziehung zeigt von der zu delegierenden Schnittstelle der Subkomponente auf die delegierende Schnittstelle der übergeordneten Komponente.

Da in der Systemarchitektur nicht nur reine Software betrachtet wird, ist es oft wichtig, zwischen verschiedenen Arten von Schnittstellen zu unterscheiden. Mögliche Arten sind die logischen Schnittstellen, die physikalischen (eventuell noch unterteilt in mechanische und elektronische) Schnittstellen sowie die Testschnittstellen. Auch hier lässt sich das Prinzip der Stereotypisierung anwenden. So hat man die Möglichkeit, Schnittstellen über die Stereotypen <<logical interface>>, <<physical interface>> und <<test interface>> näher zu definieren.

Wie geht es weiter im Projekt?

Während die gefundenen Hardwarekomponenten einer Systemarchitektur relativ losgelöst voneinander entwickelt werden können, kommt den Softwarekomponenten eine Sonderrolle zu. Diese werden in den meisten Fällen wieder in einen Topf geworfen und einer expliziten Softwareanalyse unterzogen. Es liegt nahe, dass sich gewisse Aufgaben der Softwarekomponenten wiederholen und somit eine getrennte Entwicklung nach Systemkomponenten eine unnötige Mehrarbeit bedeuten würde - vorausgesetzt, dass die Software nicht ebenfalls durch den externen Zulieferer realisiert wird. Anschließend wird dann die zu entwickelnde Software in der Softwarearchitektur logisch zerlegt und danach zu den aus der Systemarchitektur geforderten Teilen zusammengesetzt. (ue)