Real Time Object Oriented Modeling (ROOM) ist eine domänenspezifische Sprache.
ROOM wurde Anfang der 90er zur Modellierung von Echtzeitsystemen entwickelt. Ursprünglich für den Bereich der mobilen Telekommunikation mit einem Fokus auf Einfachheit und Performanz entwickelt, lässt sich die ROOM-Sprache für beliebige ereignisgetriebene Echtzeitsysteme nutzen.
ROOM wird z. B. von den Werkzeugen ObjecTime Developer (kommerziell) und eTrice (Open Source) unterstützt.
Viele Grundkonzepte von ROOM sind in die Definition von UML2 (Version 2 der UML mit Echtzeiterweiterungen) eingeflossen.
Konzepte und Grundbegriffe
ROOM ist eine Modellierungssprache zur Beschreibung von Softwaresystemen, die die vollständige Generierung des Programmcodes für das System aus dem Modell erlaubt. ROOM definiert dafür eine textuelle wie auch eine grafische Beschreibungssprache. Typischerweise wird der generierte Code durch manuellen Code ergänzt, etwa für eine grafische Benutzeroberfläche (GUI). Der Code wird dann gegen eine Laufzeitbibliothek kompiliert und gelinkt, die Basisklassen und grundlegende Dienste (wie etwa das Messaging) zur Verfügung stellt.
ROOM kennt drei Aspekte eines Software-Systems: Struktur, Verhalten und Vererbung. Diese Aspekte sollen in den folgenden Abschnitten kurz erläutert werden.
Struktur
Die strukturelle Sicht ist in ROOM aus sogenannten Aktoren aufgebaut. Aktoren können mit anderen Aktoren über Ports kommunizieren. Ports sind miteinander über Bindings verbunden. Aktoren tauschen über Ports und Bindings Nachrichten aus, die asynchron verschickt werden. Jeder Port ist genau einem Protokoll zugeordnet. Ein Protokoll in ROOM definiert einen Satz von eingehenden und einen Satz von ausgehenden Nachrichten. Bindings können nur Ports verbinden, die zum gleichen Protokoll gehören und die zueinander konjugiert sind. Das bedeutet, dass der eine Port die eingehenden Nachrichten des Protokolls empfängt und die ausgehenden sendet. Dieser Port wird auch regulär genannt. Sein Gegenüber, der konjugierte Port, empfängt die ausgehenden Nachrichten des Protokolls und sendet die eingehenden. Somit vereint ein Port ein required und ein provided Interface in einer Rolle (da das gleiche Protokoll von mehreren Ports eines Aktors verwendet werden kann).
Ein Aktor kann auch andere Aktoren enthalten (als Komposition). In ROOM werden diese Aktorreferenzen genannt. So können strukturelle Hierarchien beliebiger Tiefe gebildet werden.
Die Ports eines Aktors können Teil seines Interfaces (also außen sichtbar) oder Teil seiner Struktur (also von ihm selbst verwendet) oder beides sein. Ports, die nur zum Interface gehören, werden Relay Ports genannt. Sie sind direkt mit dem Port eines Subaktors (einer Aktorreferenz) verknüpft. Ports, die nur zur Struktur gehören, werden interne End Ports genannt. Ports, die zu Struktur und Interface gehören, werden externe End Ports genannt.
Verhalten
Jeder Aktor in ROOM besitzt ein Verhalten in Form eines hierarchischen Zustandsautomaten (engl. State Machine). Ein Zustandsautomat ist ein gerichteter Graph, der aus States genannten Knoten und Transitions genannten Kanten besteht. Jeder State entspricht einem Zustand. Zustandswechsel können nur entlang einer Transition stattfinden. Zustandswechsel werden ausgelöst durch eine an einem (internen oder externen) End Port eingehende Nachricht (die in diesem Zusammenhang auch Event oder Signal genannt wird). Wird dieser sogenannte Trigger von der Transition spezifiziert, so feuert diese genau dann, wenn der Zustandsautomat sich im Ausgangszustand der Transition befindet. Anschließend wechselt der Zustandsautomat in den Zielzustand der Transition.
Dabei werden beim Zustandswechsel Codestücke ausgeführt, die der Programmierer/Modellierer an die States und Transitionen anhängt. Solche Codestücke werden in einer Detail Level Language, meist der Zielsprache der Codegenerierung, verfasst. Beim State unterscheidet man Entry und Exit Code. Bei einem Zustandswechsel wird zunächst der Exit Code des Ausgangszustands ausgeführt, dann der Action Code der feuernden Transition und schließlich der Entry Code des Zielzustands. Sehr häufig wird von solchen Code Stücken eine Nachricht über einen Port des Aktors gesendet.
Weitere Elemente eines Zustandsautomaten sind die Choice Points und die Transition Points, auf die hier nicht weiter eingegangen werden soll.
Ein Zustandsautomat kann weitere Hierarchieebenen einführen, in dem einzelne Zustände wieder einen Unter-Zustandsautomaten besitzen. Ähnlich wie bei der Struktur kann dies bis zu beliebiger Tiefe fortgesetzt werden.
Ein wichtiges Konzept in Zusammenhang ist schließlich noch das Ausführungsmodell der Run to Completion. Damit ist gemeint, dass ein Aktor eine empfangene Nachricht vollständig verarbeitet, bevor er die nächste verarbeitet. Da die Run to Completion Semantik von der Ausführungsumgebung garantiert wird, muss sich der Programmierer/Modellierer nicht separat um Synchronisierung und Thread-Sicherheit kümmern, obwohl mit ROOM implementierte Systeme hochgradig nebenläufig sein können.
Vererbung
Wie jede objektorientierte Programmiersprache ist ROOM ein Klassenmodell. D.h. Aktoren sind Klassen, die mehrfach als Objekte instantiiert werden können. Jede einzelne Instanz einer Klasse kann dabei in einem anderen Zustand sein und auch mit anderen Instanzen derselben Klasse kommunizieren.
ROOM kennt auch den Begriff der Vererbung im Sinne einer Einfachvererbung. Das heißt, eine Aktorklasse kann von einer anderen (ihrer Basisklasse) abgeleitet sein und erbt dabei alle Eigenschaften ihrer Basisklasse, also etwa Ports und Aktorreferenzen, aber auch den Zustandsautomat. Der geerbte Zustandsautomat kann von der abgeleiteten Klasse um weitere Transitionen und Zustände erweitert werden.
Layering
Ein letztes mächtiges Konzept in ROOM ist das sogenannte Layering. Damit ist eine vertikale Schichtung des Systems in Dienste und Nutzer dieser Dienste gemeint. ROOM führt dafür die Begriffe Service Access Point (SAP) auf der Seite des Nutzers und Service Provision Point (SPP) auf der Bereitstellungsseite eines Dienstes ein. Interessant ist dabei, dass SAPs nicht wie Ports explizit mit SPPs verbunden werden müssen. Vielmehr kann ein Aktor per Layer Connection an einen Dienst angebunden werden und stellt diesen allen Subaktoren (rekursiv) zur Verfügung. Ansonsten sind Dienste und ihre Nutzer wie Ports mit Protokollen verknüpft und kommunizieren über asynchron verschickte Nachrichten.
Literatur
- Bran Selic, Garth Gullekson, Paul T. Ward: Real-Time Object-Oriented Modeling, New York, John Wiley & Sons Inc, 1994, ISBN 978-0-471-59917-3
- Neue Edition: Bran Selic, Garth Gullekson, Paul T. Ward: Real-Time Object-Oriented Modeling, Hamburg, MBSE4U, 2023, ISBN 978-3-982-22354-4
- Oliver Kaiser: „Echtzeitanforderungen zur Simulation technischer Produkte“, Herbert Utz Verlag, 2000, ISBN 3-89675-734-2