-
TECHNISCHES
FELD DER ERFINDUNG
-
Diese Erfindung bezieht sich allgemein
auf das Gebiet der Computersoftware. Spezieller bezieht sich die
Erfindung auf ein Verfahren zur Konstruktion von dynamischen Objekten
für ein
Anwendungsprogramm.
-
HINTERGRUND DER ERFINDUNG
-
Das Schreiben von Software-Anwendungen für Probleme
der wirklichen Welt, wie zum Beispiel Fernsprechvermittlungs-Kommunikationsprotokolle, ist
eine extrem komplizierte Prozedur. Solche Software-Anwendungen erfordern
für die
Erstellung viele Stunden, werden oft mit zahlreichen Problemen ausgeliefert
und sind schwierig zu ändern
und zu unterstützen.
Der Grund für
die Schwierigkeiten bei der Erstellung und Unterstützung großer Anwenderprogramme
ist hauptsächlich
die Unfähigkeit
existierender Softwareentwicklungs-Paradigmen, einen Rahmen zur
Vereinfachung des Software-Entwicklungsprozesses
bereitzustellen. Es hat sich gezeigt, dass die Komplexität der Software
sich als Exponentialfunktion der Anzahl verschiedener Operationen
erhöht,
von denen erwartet wird, dass sie mit derzeitigen Paradigmen verarbeitet
werden. Es kann sein, dass ein Programm mit 1000 Zeilen einen Monat
Entwicklungszeit benötigt,
und im Gegensatz dazu kann ein Programm mit 2000 Zeilen einen Entwicklungsaufwand
von sechs Monaten oder mehr erfordern. In der Vergangenheit lagen
große
Programmieranstrengungen fast jenseits der Möglichkeiten der Entwicklung
bezüglich
einer vernünftigen
Leistungsfähigkeit, Zuverlässigkeit,
vernünftiger
Entwicklungskosten und Entwicklungszyklen.
-
Die objektorientierte Technologie
(OOT) verbessert die Produktivität
immer dann, wenn ein Problem vereinfacht werden kann, indem man
es in einen Satz von Black-Box-Objekten
zerlegt. Die objektorientierte Technologie ist von den Vorteilen
des Verbergens von Daten, der Vererbung und der Polymorphie abhängig, um
ein Software-Design zu vereinfachen. Wenn eine Anwendung nicht in
Objekte unterteilt werden kann, bietet die objektorientierte Technologie
keine bedeutende Verbesserung der Produktivität. Die objektorientierte Technologie
behandelt auch nicht, wie das zugrunde liegende Verhalten eines
Objektes konstruiert werden muss, das sein Verhalten als Funktion
der Reihenfolge, in der Ereignisse eintreffen, ändern muss. Das zugrunde liegende
Verhalten eines Objektes mit dieser Art von Anforderungen wird am
besten unter Verwendung der Methoden der endlichen Automaten konstruiert.
-
Die aktuelle Zustands-/Ereignis-Softwarestrategie
ist es, jeden Schritt bei der Verarbeitung einer Zustandsnummer
zuzuweisen. Es wird ein Entscheidungsbaum oder eine Entscheidungstabelle verwendet,
ein Ereignis zu einer Verarbeitungs-Route zu leiten, die für den derzeitigen
Zustand und das Ereignis spezifisch ist. Weder eine funktionelle,
noch eine objektorientierte Design-Strategie verringert die Komplexität und die
Menge der Software zur Verarbeitung von Zuständen/Ereignissen, und zwar
aus folgenden Gründen:
- – Es
sind tief verschachtelte Funktionsaufrufe erforderlich, um die Größe des Programms
zu verringern. Dieses tiefe Verschachteln erschwert das Verständnis der
Funktion des Systems und vergrößert den
Abstand der Software-Implementation von einer graphischen Darstellung,
wie z. B. einem Zustandsdiagramm.
- – Ein
einziges Ereignis kann zu einer von vielen möglichen Zustandsänderungen
führen.
Der spezielle Zustand ist oft eine Funktion verschiedener Status-
und Datenbank-Parameter.
Wenn die Bedingungen, die erforderlich sind, einen bestimmten Zustandsübergang
durchzuführen,
nicht grafisch spezifiziert werden können, wie für den Fall des Zustands als
Nummern-Paradigma, wird das Verständnis der Funktion des Automaten
erschwert.
- – Es
ist schwierig eine Implementation eines komplizierten endlichen
Automaten (Finite State Machine, FSM) zu analysieren. Die zugrunde
liegenden Zustands-Ereignis-Zusammenhänge werden von
einem Software-Ingenieur am besten verstanden, wenn sie in einer
grafischen Darstellung ausgedrückt
werden, in der die Zustände
als Kreise oder Kästen
und die Ereignisse, die zu Transaktionen zu neuen Zuständen führen, als
Bögen zwischen
den Zuständen
gezeichnet werden. Diese grafische Darstellung kann man in der Software-Implemention
nicht mehr finden, da die zur Implementation der Zustandsänderungen
benötigten
Software-Operationen über
die gesamte Software verteilt sind. Daher muss die anfängliche Software-Implementation
aus ihrer grafischen Darstellung manuell codiert werden. Vorhandene Programme,
bei denen die anfängliche
Dokumentation verloren gegangen ist oder fehlt, erfordern einen
umfangreichen Prozess zur Wiederherstellung der mehr intuitiven
grafischen Darstellung.
- – Bei
Softwareänderungen
werden häufig
Fehler eingeführt,
weil bei der Änderung
vergessen wurde, einen Zeitgeber anzuhalten oder beim Verlassen
des Zustandes eine Ressource wieder freizugeben. Der Zustand als
Nummern-Paradigma versteckt die Einrichtungen, die zugeteilt wurden.
- – Die
meisten Implementationen enthalten zahlreiche Ereignis-Routinen
mit ähnlichem,
aber nicht ganz identischem Verhalten. Die Anzahl von Fehlern in
einem System erhöht
sich normalerweise mit der Größe der Software.
Durch Beseitigung von redundantem Code sollte sich die Zuverlässigkeit
eines Systems erhöhen.
- – Das
Zustands-Design führt üblicherweise
zu einer ebenen Architektur (im Gegensatz zu einer hierarchischen),
was zu einem komplexen Design führt.
Hierarchische Automaten sind selbstverständliche Lösungen für manche Probleme, wie zum
Beispiel Kommunikationsprotokolle, aber andere Probleme erfordern
einen tiefen Einblick in den Problembereich, um eine Zerlegung in
zwei oder mehr Hierarchieebenen zu ermöglichen. Eine ebene Architektur
ist aus den folgenden Gründen
schwierig aufrecht zu erhalten:
- – Die
Anzahl von Verbindungen zwischen den Zuständen ist groß.
- – Redundante
Zustände
mit ähnlichem
Verhalten verbinden verschiedene Zustände. Komplexe Designs sind
fehleranfälliger
als einfachere Designs.
- – Die
automatische Erzeugung und der Test des Anwendungs-Automaten aus
einer grafischen Spezifikation sind normalerweise wegen der zufälligen Natur
der durchgeführten
Verarbeitung und der Verteilung der Zustandswechsel nicht machbar.
-
Alle der oben angeführten Faktoren
machen es schwer, die Produktivität der Entwicklung von komplexer
Software zu verbessern. Das objektorientierte Paradigma kann nicht
selbst verwendet werden, um die Qualität zu verbessern und die Entwicklungskosten
von komplizierten Software-Automaten zu verringern. Die objektorientierte
Technologie behandelt nicht die Arbeitsweise im Innern des Zustands-/Ereignis-Codes
eines Objektes. Die grundlegende Schwierigkeit mit dem Paradigma
der Software-Automaten ist, dass es einen Automaten als Sammlung
von Zustandsnummern und Ereignis-Routinen modelliert.
-
In
US
5,555,415 wird ein Ereignis-Abfertigungs-Untersystem offen
gelegt, das eine Vorverarbeitung von Ereignis-Nachrichten durchführt, die
von einem durch Ereignisse getriebenen Hauptsystem empfangen wurden.
Es wird eine Darstellung eines Automaten offen gelegt.
-
In Joint Object Services Submission,
Life Cycle Services Specification OMG, 2. Juli 1993 Seite 1 bis
50, wird eine allgemeine Lösung
für die
Entwicklung objektorientierter Software offen gelegt. Das Verschieben
oder Kopieren eines Objektes von einer Stelle zu einer anderen wird
offen gelegt.
-
ZUSAMMENFASSUNG DER ERFINDUNG
-
Demgemäß ist es wünschenswert geworden, einen
Weg oder einen Rahmen bereitzustellen, um komplexe Software-Anwendungen
zu entwickeln, der sie leichter verständlich macht und die Fehlersuche
und den Test erleichtert, während
sie weiter für Echtzeitanwendungen
effizient bleibt. Weiterhin ist es wünschenswert, einen Rahmen bereitzustellen,
der eine weitgehend direkte Umwandlung einer grafischen Darstellung
des Automaten-Diagramms in Code erlaubt. Insbesondere kann ein Zustandsdiagramm,
das nach dem Mealy- oder Moore-Zustandsmodell modelliert ist, leicht
in wiederverwendbaren Code für
die Software-Anwendung umgewandelt werden, indem man den von der
vorliegenden Erfindung bereitgestellten Rahmen benutzt.
-
Zusätzlich dazu ist es wünschenswert,
die Objekte, mit denen die Software-Anwendung implementiert wird, aus einem
hierarchischen Satz von Konfigurationsdateien dynamisch zu erzeugen.
Die Konfigurationsdateien können
einfach geändert
werden, um die resultierende Software-Anwendung zu ändern, ohne
dass der Code erneut einen Compiler oder Linker durchlaufen muss.
Es ist auch wünschenswert,
dass kein Verlust an Echtzeit-Leistungsfähigkeit
als Folge der Fähigkeit,
Objekte zur Laufzeit dynamisch zu erzeugen, auftritt. Auf diese
Weise wird der Prozess der Software-Implementation weiter rationalisiert.
-
Gemäß eines Aspektes der vorliegenden
Erfindung wird ein Verfahren zur Konstruktion dynamischer Objekte
für eine
Anwendungs-Software bereitgestellt, das folgende Schritte umfasst:
Umwandlung einer Darstellung des Zustandsdiagramms der Software-Anwendung
in eine Haupt-Konfigurationsdatei; Lesen und Syntaxanalyse der Haupt-Konfigurationsdatei
durch ein Foreman-Objekt; Gewinnung einer Objekt-Kennung (Object-ID)
für jedes
dynamische Objekt, das in der Haupt-Konfigurationsdatei spezifiziert
ist; Erzeugung einer Instanz jedes dynamischen Objektes, das in
der Haupt-Konfigurationsdatei
spezifiziert ist, durch ein Factory-Objekt und Gewinnung einer physikalischen
Adresse für
jede erzeugte Instanz; Speicherung der Objekt-Kennungen und der physikalischen
Adressen der erzeugten Instanzen in einem Objekt-Verzeichnis; Aufruf
eines Initialisierungs-Verfahrens für jedes Objekt, das im Objekt-Verzeichnis
gespeichert ist; und Steuerung der Initialisierung jeder erzeugten
Instanz.
-
Gemäß eines anderen Aspektes der
vorliegenden Erfindung wird ein System zur dynamischen Implementation
einer Software-Anwendung bereitgestellt, das folgendes umfasst:
Eine Datenbank, die eine Zustandsdiagramm-Darstellung der Software-Anwendung
enthält,
wobei die Datenbank so angepasst ist, dass sie die Zustandsdiagramm-Darstellung
in einen Satz von Konfigurationsdateien umwandelt, die hierarchisch
organisiert sind, wobei sich Konfigurationsdateien einer höheren Ebene
auf Konfigurationsdateien einer niedrigeren Ebene beziehen, und
wobei die Konfigurationsdateien eine Spezifikation eines Satzes
hierarchisch organisierter dynamischer Objekte und deren Attribute
zur Implementation der Software-Anwendung enthalten; ein Foreman-Objekt,
das den Satz von Konfigurationsdateien liest und eine Syntaxanalyse
durchführt,
wobei das Foreman-Objekt so angepasst ist, dass es für jedes dynamische
Objekt eine Objekt-Kennung liefert; ein Factory-Objekt, das so angepasst
ist, dass es eine Instanz einer bestimmten Klasse dynamischer Objekte
erzeugt, die in den Konfigurationsdateien spezifiziert sind, und
eine physikalische Adresse für
jede erzeugte Instanz erhält;
und ein Objekt-Verzeichnis, das so angepasst ist, dass es die Objekt-Kennungen und die
physikalischen Adressen der erzeugten Instanzen speichert, wobei
das Objekt-Verzeichnis so angepasst ist, dass es jede erzeugte Instanz
initialisiert.
-
In einer Ausführung der vorliegenden Erfindung
umfasst ein Verfahren zur Konstruktion dynamischer Objekte für eine Anwendungs-Software
die Schritte des Lesens und der Syntaxanalyse einer Haupt-Konfigurationsdatei
durch ein Foreman-Objekt, des Erhaltens einer Objekt-Kennung (Object-ID) für jedes
dynamische Objekt, das in der Haupt- Konfigurationsdatei spezifiziert ist,
des Erzeugens einer Instanz jedes dynamischen Objektes, das in der Haupt-Konfigurationsdatei
spezifiziert ist, durch ein Factory-Objekt und des Erhaltens einer
physikalischen Adresse für
jedes erzeugte Objekt, der Speicherung der Objekt-Kennungen und
der physikalischen Adressen der erzeugten Objekt-Instanzen in einem
Objekt-Verzeichnis, des Aufrufs des Initialisierungs-Verfahrens
für jedes
Objekt, das im Objekt-Verzeichnis gespeichert ist und der Initialisierung jedes
erzeugten Objektes.
-
In einer Ausführung der vorliegenden Erfindung
enthält
ein System zur dynamischen Implementation einer Software-Anwendung
einen Satz von Konfigurationsdateien, die hierarchisch organisiert sind,
wobei sich Konfigurationsdateien einer höheren Ebene auf Konfigurationsdateien
einer niedrigeren Ebene beziehen, und wobei die Konfigurationsdateien
eine Spezifikation eines Satzes hierarchisch organisierter dynamischer
Objekte und deren Attribute zur Implementation der Software-Anwendung
enthalten. Ein Foreman-Objekt ist so angepasst, dass es den Satz
von Konfigurationsdateien liest und eine Syntaxanalyse durchführt und
für jedes
dynamische Objekt eine Objekt-Kennung liefert. Ein Factory-Objekt
ist so angepasst, dass es eine Instanz einer bestimmten Klasse dynamischer
Objekte erzeugt, die in den Konfigurationsdateien spezifiziert sind,
und eine physikalische Adresse für
jedes erzeugte Objekt erhält.
Ein Objekt-Verzeichnis speichert die Objekt-Kennungen und die physikalischen Adressen
der erzeugten Objekt-Instanzen und steuert die Initialisierung jedes
erzeugten Objektes.
-
Ein wichtiger technischer Vorteil
stellt den Zustand als Objekt-Paradigma bereit, der im Rahmen einer
Ausführung
der vorliegenden Erfindung verkörpert
wird. Gemäß dieses
Zustandes als Objekt-Paradigma kann eine Software-Applikation, die nach
dem Mealy- oder Moore-Zustandsdiagramm konstruiert wurde, leicht
in Code mit wiederverwendbaren Objektklassen umgewandelt werden.
Da der Zustand in einem Objekt verkörpert wird, ist die Zustandsobjektklasse
wiederverwendbar, um viele Instanzen davon in der Software-Implementation bereitzustellen.
Weiterhin können
zum Beispiel in einem Moore-Zustandsdiagramm
die Zustände
im Zustandsdiagramm leicht auf Zustandsobjekte abgebildet werden,
und die Bögen
im Zustandsdiagramm können
leicht auf Ereignis-Objekte abgebildet werden. Auf gleiche Weise
kann die Analyse einer Software-Anwendung, die mit dem Rahmen einer
Ausführung
der vorliegenden Erfindung konstruiert wurde, leicht durchgeführt werden,
indem man die Zustandsobjekte auf Zustände in einem Moore-Zustandsdiagramm
abbildet und die Ereignis-Objekte auf Bögen in dem Diagramm abbildet.
Daher wird der Prozess der Codierung komplexer Software-Anwendungen
wesentlich vereinfacht und rationalisiert, was zu einer höheren Produktivität führt.
-
Weiterhin muss, da die Objekte in
Konfigurationsdateien spezifiziert sind, für Modifikationen und Änderungen
von Code nicht erneut ein Compiler oder Linker durchlaufen werden,
sondern dies kann online zur Laufzeit erfolgen. Da die Konfigurationsdateien und
die Factory-Objekte unabhängig
und auf hierarchische Weise organisiert sind, können sie geändert werden, ohne die anderen
zu beeinflussen. Die Laufzeit-Effizienz der Anwendungs-Software wird auch dadurch
erreicht, dass die dynamischen Objekte aus Objektklassen erzeugt
werden, die in einer compilierten Hochsprache, wie z. B. C++ und
nicht in einer interpretierten Sprache implementiert sind.
-
KURZBESCHREIBUNG DER ZEICHNUNGEN
-
Für
ein besseres Verständnis
der vorliegenden Erfindung wird auf die folgenden begleitenden Zeichnungen
Bezug genommen:
-
1 ist
ein vereinfachtes Blockdiagramm eines Software-Automaten gemäß einer
Ausführung der
vorliegenden Erfindung;
-
2 ist
ein vereinfachtes Blockdiagramm eines Zustandes als Objekte gemäß einer
Ausführung
der vorliegenden Erfindung;
-
3 ist
ein Zustands-Kontext-Diagramm gemäß einer Ausführung der
vorliegenden Erfindung;
-
4 ist
ein Kontext-Diagramm des Initialisierungsprozesses, in dem Anwendungs-Objekte
gemäß einer
Ausführung
der vorliegenden Erfindung erzeugt werden;
-
5 ist
ein Diagramm der grundlegenden Ebenen-Architektur des Software-Automaten gemäß einer
Ausführung
der vorliegenden Erfindung;
-
6 ist
ein Automaten-Kontext-Diagramm gemäß einer Ausführung der
vorliegenden Erfindung;
-
7 ist
ein Logik-Flussdiagramm der Nachrichtenverarbeitung im Software-Automaten gemäß einer
Ausführung
der vorliegenden Erfindung;
-
8 ist
ein Diagramm eines Beispiels mit mehreren Anwendungen gemäß einer
Ausführung der
vorliegenden Erfindung;
-
9 ist
ein Vererbungs-Diagramm von Objektklassen gemäß einer Ausführung der
vorliegenden Erfindung;
-
10 ist
ein Vererbungs-Diagramm der Klasse FsmEntity gemäß einer Ausführung der
vorliegenden Erfindung;
-
11 ist
ein Vererbungs-Diagramm der Klasse FsmCollection gemäß einer
Ausführung
der vorliegenden Erfindung;
-
12 ist
ein Kontext-Diagramm eines dynamischen Arrays gemäß einer
Ausführung
der vorliegenden Erfindung;
-
13 ist
ein Zustandsklassen-Vererbungs-Diagramm gemäß einer Ausführung der
vorliegenden Endung;
-
14 ist
ein Ereignisklassen-Vererbungs-Diagramm gemäß einer Ausführung der
vorliegenden Erfindung;
-
15 ist
ein Nachrichtenklassen-Vererbungs-Diagramm gemäß einer Ausführung der
vorliegenden Erfindung;
-
16 ist
ein Kontext-Diagramm von Foundry-Objekten gemäß einer Ausführung der
vorliegenden Erfindung;
-
17 ist
ein Vererbungs-Diagramm der Klasse OutgoingMessageFoundy gemäß einer
Ausführung
der vorliegenden Endung;
-
18 ist
ein Kontext-Diagramm der Klasse PortMessageFoundy gemäß einer
Ausführung
der vorliegenden Erfindung;
-
19 ist
ein Kontext-Diagramm von Befehlsklassen gemäß einer Ausführung der
vorliegenden Erfindung;
-
20 ist
ein Vererbungs-Diagramm von Befehlsklassen gemäß einer Ausführung der
vorliegenden Erfindung;
-
21 ist
ein Kontext-Diagramm der Zeitgeber-Klassen gemäß einer Ausführung der
vorliegenden Erfindung;
-
22 ist
ein Vererbungs-Diagramm der Zeitgeber-Warteschlangen-Klasse gemäß einer
Ausführung
der vorliegenden Erfindung;
-
23 ist
ein Vererbungs-Diagramm der Klasse QueueHead gemäß einer Ausführung der vorliegenden
Erfindung;
-
24 ist
ein Vererbungs-Diagramm der Klasse Thread gemäß einer Ausführung der
vorliegenden Erfindung;
-
25 ist
ein Kontext-Diagramm der Klasse Thread gemäß einer Ausführung der
vorliegenden Erfindung;
-
26 ist
ein Kontext-Diagramm der Klasse TimerThread gemäß einer Ausführung der
vorliegenden Erfindung;
-
27 ist
ein Kontext-Diagramm der Klasse QueueThread gemäß einer Ausführung der
vorliegenden Erfindung;
-
28 ist
ein Kontext-Diagramm der Klasse QueueClientThread gemäß einer
Ausführung
der vorliegenden Endung;
-
29 ist
ein Kontext-Diagramm der Klasse DispatcherThread gemäß einer
Ausführung
der vorliegenden Erfindung;
-
30 ist
ein Vererbungs-Diagramm der Klasse Tracer gemäß einer Ausführung der
vorliegenden Erfindung;
-
31A und 31B sind Ausführungs-Flussdiagramme
von Tracer gemäß einer
Ausführung
der vorliegenden Erfindung;
-
32A bis 32C sind Ausführungs-Flussdiagramme
von ThrottleTracer gemäß einer
Ausführung der
vorliegenden Erfindung;
-
33 ist
ein Vererbungs-Diagramm der Klasse TraceObject gemäß einer
Ausführung
der vorliegenden Erfindung;
-
34 ist
ein Vererbungs-Diagramm der Klasse StateFactory gemäß einer
Ausführung
der vorliegenden Erfindung;
-
35 ist
ein Ereignisklassen-Vererbungs-Diagramm gemäß einer Ausführung der
vorliegenden Erfindung;
-
36 ist
ein Vererbungs-Diagramm der Klasse FsmEntityFactory gemäß einer
Ausführung der
vorliegenden Erfindung;
-
37 ist
ein Vererbungs-Diagramm der Klasse ThreadFactory gemäß einer
Ausführung
der vorliegenden Erfindung;
-
38 ist
ein Vererbungs-Diagramm der Klasse QueueHeadFactory gemäß einer
Ausführung der
vorliegenden Erfindung; und
-
39 ist
ein Vererbungs-Diagramm der Klasse OutgoingMessageFoundryFactory
gemäß einer
Ausführung
der vorliegenden Erfindung.
-
DETAILLIERTE BESCHREIBUNG
DER ERFINDUNG
-
Die bevorzugten Ausführungen
der vorliegenden Erfindung werden in den 1–39 veranschaulicht, wobei
gleiche Referenznummern verwendet werden, um sich auf gleiche oder
entsprechende Teile der verschiedenen Zeichnungen zu beziehen.
-
Extrem komplexe Hardware-Automaten
werden typischerweise durch Mikroprogrammierung implementiert. Mikroprogrammierte
Hardware-Automaten vereinfachen die Komplexität der Hardware und verringern
die Anzahl von Bauelementen. Mikroprogrammierte Hardware-Automaten
werden typischerweise unter Verwendung eines Speichers konstruiert, der
in Felder unterteilt ist, wobei jedes Speicherfeld den Betrieb einer
Untermenge der Hardware steuert. Mikroprogrammierte Hardware-Automaten
sind sehr regelmäßig aufgebaut
und einfach zu ändern,
wobei nur der Inhalt des Speichers geändert werden muss. Der Zustand
des Hardware-Automaten ist die Adresse des aktuellen Mikrobefehls
im Speicher. Hardware-Automaten liefern typischerweise Ausgangssignale
als Funktion des aktuellen Zustandes. Der nächste Zustand, den ein Hardware-Automat
einnimmt, wird komplett vom aktuellen Zustand und den Eingangsdaten
bestimmt. Software-Automaten
können
das Hardware-Paradigma nachbilden, indem die Ausgänge (Nachrichten,
Status und Hardwareänderungen)
dem aktuellen Zustand zugeordnet werden und nicht dem zum Ereignis
gehörenden Übergang. Ein
entscheidender Teil der Erfindung ist, dass der Zustand eines Objektes
aus einer Nummer in ein Objekt mit Eigenschaften und einem Verhalten
umgewandet wird. Damit ein Objekt sein Verhalten leicht anpassen
kann, muss der Zustand eines Objektes ein statisches Objekt sein,
der mit dem ursprünglichen
Objekt durch Verknüpfung
in Zusammenhang steht. Das Objekt ändert den Zustand, indem es
seine Verknüpfung
zu einem anderen Objekt ändert.
Polymorphes Verhalten zu Ereignissen wird behandelt, indem das Zustandsobjekt
zur Verarbeitung des Ereignisses zugewiesen wird.
-
1 ist
ein Blockdiagramm eines Beispiels für einen mikroprogammierten
Software-Automaten 10, der auf einem Zustand als Nummern-Paradigma oder
auf einem Zustand als Objekt-Paradigma basieren kann. Wenn er auf
einem Zustand als Nummern-Paradigma
basiert, ist der Automat nicht wiederverwendbar, da das anwendungsspezifische
Verhalten, wie z. B. Formate eintreffender Nachrichten und Attribute
nicht vom allgemeinen Verhalten getrennt werden können. Die
Attribute 0 bis (N – 1)
sind die Aktionen, die Software-Automat 10 ausführen kann,
wie z. B. Zeitgeber-Wert, Hardware-Zustand und zu sendende Nachricht.
Aus diesen Attributen werden Ausgaben erzeugt. In Software-Automat 10 können abstrakte
Schnittstellen zum Empfang eines Ereignisses, zur Verarbeitung des
Ereignisses, zum Eintritt in einen Zustand und zum Verlassen eines
Zustandes in einem Satz von Objektklassen definiert werden, die
keinen anwendungsspezifischen Code enthalten. Diese Klassen sind
als Startpunkt zur Implementation von Anwendungsprogrammen wiederverwendbar.
Der Programmierer definiert die Attribute in einem abgeleiteten
Zustand, die für
die Anwendung erforderlich sind, und implementiert die Behandlungsroutinen
für das
Eintreten und das Verlassen. Die Behandlungsroutinen für das Eintreten
und das Verlassen entsprechen der wahlfreien Logik in einem Hardware-Automaten,
die von dem Inhalt des mikroprogrammierten Speichers angesteuert
wird. Es kann ein Werkzeug mit grafischer Benutzerschnittstelle
(Graphical User Interface, GUI) verwendet werden, um Anwendungsprogramme
aufzubauen, indem Instanzen von Zuständen und anderen Objekten auf
diagrammatikalische Weise erzeugt, sie verbunden und die erforderlichen
Attribute ausgefüllt werden.
-
Insbesondere kann der Programmierer
mit der Implementation der Software-Anwendung beginnen, indem er zunächst einen
Satz von hierarchischen Zustandsdiagrammen erzeugt. Nach dem Moore-Modell
werden die Zustände
als Kreise gezeichnet, die durch Bögen miteinander verbunden sind,
die Eingänge
oder Ereignisse darstellen, welche Zustandsänderungen hervorrufen. Der
Zustand als Objekt-Paradigma versetzt den Programmierer in die Lage,
diese grafische Spezifikation der Software-Anwendung leicht in Code
umzusetzen, indem er die Zustände
im Diagramm in Zustandsobjekte und die Bögen im Diagramm in Ereignis-Objekte
umwandelt. Die Analyse wird durch den Zustand als Objekt-Paradigma auch vereinfacht.
Die Zustandsobjekte in der Anwendungs-Software können in Kreise im Zustandsdiagramm
umgewandelt werden, und die Ereignis-Objekte können in Bögen umgewandelt werden, mit
denen die Kreise verbunden sind.
-
2 ist
ein vereinfachtes Blockdiagramm der Zustände als Objekt-Paradigmen gemäß einer Ausführung der
vorliegenden Erfindung. Bei der normalen objektorientierten Programmierung
wird nicht berücksichtigt,
dass ein Objekt sein Verhalten als Folge des Empfangs eines Ereignisses ändert. Polymorphie
in Sprachen, wie z. B. C++, erlaubt es verschiedenen Objekten, einheitlich
auf ein Ereignis zu reagieren, erlaubt es aber nicht, dass einzelne
Objekte ihr Verhalten mit der Zeit ändern. Die Instanzen des endlichen
Automaten, sein Satz von Zuständen
und Ereignis-Behandlungsroutinen können als erweitertes Objekt
betrachtet werden, in dem alle von ihnen für die Einheit der höheren Ebene
benötigt
werden, um ihr Verhalten zu implementieren. Beim Zustand als Objekt-Paradigma
wird ein Objekt 20 verwendet, um die Daten und die Methoden
eines Zustandes zusammenzufassen. Wenn ein bestimmtes Ereignis 22 auf
Objekt 20 trifft, wird Objekt 20 einem bestimmten Zustandsobjekt
N 26 zugeordnet. Objekt 20 kann die Zustände ändern, indem
es seine Verknüpfung
zu verschiedenen Zustandsobjekten 26 ändert. Das polymorphe Verhalten
gegenüber
Ereignissen wird behandelt, indem Zustandsobjekt 26 zugewiesen
wird, um Ereignis 22 zu bearbeiten.
-
Ein Satz von Zustands-/Ereignis-Klassen wurde
entwickelt, der auf dem Paradigma von Zuständen als Objekte basiert. Die
Operationen, die zum Eintreten in einen Zustand erforderlich sind,
sind aus Ereignis-Funktionen entfernt und in Eintritts-Funktionen
platziert, die mit dem Zustand verknüpft sind. Die Eintritts-Verarbeitung
wird automatisch als Folge des Eintritts in einen Zustand ausgelöst. Die
Verknüpfung
der Verarbeitung mit einem Zustand anstatt mit einem Ereignis erlaubt
alle zum Eintritt in den Zustand erforderlichen allgemeinen Verarbeitungen
zu zentralisieren und in dem Zustandsobjekt zusammenzufassen. Weiterhin
werden bestimmte Funktionen, wie z. B. die Einrichtung eines Zeitgebers
bei Eintritt in einen Zustand, besser von der Zustands- als von
der Ereignis-Funktion ausgeführt,
da der Zeitgeber eingerichtet werden muss, egal welches Ereignis
den Übergang
in den Zustand ausgelöst
hat. Andernfalls muss jede Ereignis-Funktion, die zu einem Übergang
in einen Zustand führt,
die erforderliche Verarbeitung ausführen.
-
Die zum Verlassen des Zustandes erforderlichen
Operationen sind aus Ereignis-Funktionen ebenfalls
entfernt und in Eintritts-Funktionen platziert, die mit dem Zustandsobjekt
verknüpft
sind. Die Austritts-Verarbeitung wird automatisch als Folge des
Verlassens eines Zustands ausgelöst.
Die Austritts-Verarbeitung, wie z. B. das Anhalten eines Zeitgebers,
der beim Eintritt in den Zustand eingerichtet wurde, ist häufig erforderlich.
Die gleiche Ereignis-Funktion, die üblicherweise zum Verlassen
eines Zustandes führt,
muss dieselbe Austritts-Verarbeitung ausführen. Durch Automatisierung
des Löschens
des Zeitgebers werden die Ereignis-Funktionen bedeutend vereinfacht.
Durch Automatisierung der Austritts-Verarbeitung werden weniger
Fehler eingeführt,
die als Folge von beim Verlassen in einer Ereignis-Routine nicht
ausgeführten
Funktionen auftreten.
-
In dem Software-Automaten sind Attribute, die
den Betrieb der mikroprogrammierten Automaten nachahmen, bei der
Ausführung
des vom Anwender implementierten Eintritts- und Austritts-Verhaltens zulässig. Ereignis-,
Eintritts- und Austritts-Funktionen können kombiniert werden, wenn
vom Zustand abhängige
Daten entfernt werden. Der objektorientierte Automat abstrahiert
den Zustand, so dass jede Anwendung Attribute als Datenpunkte hinzufügt, wie
sie benötigt
werden, um die Anforderungen der Anwendung zu erfüllen.
-
Im Software-Automaten 10 dürfen die
Zustandsobjekte entweder stabil oder vorübergehend sein. Stabile Zustandsobjekte
fügen ein
Verhalten für die
Verarbeitung externer Ereignisse hinzu, und Objekte können zwischen
dem Auftreten von Ereignissen in einem stabilen Zustand bleiben.
Vorübergehende
Zustände
werden nur eingenommen, um eine Operation auszuführen, die mit der Verarbeitung
des Ereignisses zusammenfällt.
Vorübergehende
Zustände
können
verwendet werden, um die Tiefe von Funktionsaufrufen in Ereignis-Routinen
zu verringern, indem vorübergehende
Zustände
aneinandergereiht werden. Zum Beispiel führt jeder vorübergehende
Zustand beim Eintritt die Operationen aus, die bei einem Funktionsaufruf
erforderlich sind. Es sind mehrere Austritte aus dem vorübergehenden
Zustand erlaubt. Durch Verwendung von vorübergehenden Zuständen vereinfacht
sich die Verarbeitung, die für
einen bestimmten Zustandsübergang
erforderlich ist, sie erhöht
jedoch die Komplexität
des Zustandsdiagramms.
-
Im Software-Automaten 10 können durch
die Ereignis-Funktion keine expliziten Zustandsänderungen durchgeführt werden.
Ereignis-Funktionen sind nur erlaubt, um logische Zustandsänderungen
anzuzeigen, die in den geeigneten physikalischen Zustand umgesetzt
werden. Ereignis-Funktionen, die sich normalerweise durch die jeweiligen
Zustandsänderungen
unterscheiden würden,
können
in allgemeine Routinen zusammengelegt werden.
-
Im Software-Automaten 10 befindet
sich die Topologie der Zustandsübergänge innerhalb
der Zustandsobjekte anstatt innerhalb der Anwendungs-Funktionen.
Daher wird die Aufgabe der Wartung und Entschlüsselung der Zustands-Topologie vereinfacht,
da der Ingenieur nicht mehr schrittweise Programmcode lesen muss,
um festzustellen, welche Zustandsübergänge für einen Zustand definiert sind.
-
Im Software-Automaten 10 sind
die den Ereignis-Funktionen zugeordneten Verantwortlichkeiten begrenzt
auf die Verarbeitung des empfangenen Ereignisses und die Feststellung,
ob eine logische Zustandsänderung
erforderlich ist. Somit werden weniger und einfachere Ereignis-Funktionen
benötigt.
-
Im Software-Automaten 10 ist
die interne Struktur eintreffender Ereignisse eingeschlossen. Alle
eintreffenden Ereignisse können
als Zustands-Nachrichten-Objekte eintreten oder werden am Eingang
in ein Objekt umgewandelt, so dass alle Zugriffe auf Daten über Mitgliederfunktionen
durchgeführt
werden.
-
Im Software-Automaten-Paradigma wird auch
eine Unterstützung
für hierarchische
oder interagierende Automaten bereitgestellt. Ereignisse werden
zu dem Automaten weitergeleitet, der die Verantwortung für ihre Verarbeitung übertragen
bekommen hat. Die interne Übertragung
von Nachrichten zwischen Automaten wird unterstützt. Die Beziehung zwischen
zwei beliebigen Automaten darf hierarchisch sein, wobei Ereignisse
einer höheren
Ebene vom Automaten der obersten Ebene und Ereignisse einer niedrigeren
Ebene vom Automaten der untersten Ebene verarbeitet werden. Die
Kommunikation zwischen den beiden Ebenen von Automaten erfolgt über interne
Ereignisse. Beide Automaten können auch
eine funktionelle Beziehung zueinander haben, wobei jedem Automaten
die Verantwortung für
einen gesonderten Satz von Ereignissen zugewiesen ist und die beiden
Automaten interagieren, indem sie sich einander nach Bedarf Ereignisse
senden. Der Austausch von Ereignissen ist eine effiziente Transaktion.
Aufrufe von direkten Prozess-Nachrichten-Mitgliederfunktionen zwischen Automaten
sind zulässig.
-
3 ist
ein vereinfachtes Kontext-Diagramm einer Zustands-Klasse. Eine Instanz 30 einer Objektklasse
FsmInstance (Finite State Machine Instance) hat einen Zustands-Zeiger 32,
der auf eine Instanz 34 ihres aktuellen Zustandsobjektes
zeigt, Zustand 0. Zustand 0 34 definiert das Verhalten von FsmInstance 30 in
Form der Ereignisse 36, auf die FsmInstance 30 reagieren
kann, während
sie sich im aktuellen Zustand befindet, die im aktuellen Zustand ausgeführten Aktionen
und einen nächsten
Zustand 38, den FsmInstance 30 einnehmen kann.
Somit repräsentieren
die Zustandsobjekte 34, 38 und 40 die Zustände, in
die das Objekt FsmInstance eintreten kann und definieren auch eine
Sammlung von Ereignissen 42, die FsmInstance 30 erwarten
kann, während
sie in den Zuständen 34, 38 und 40 ist.
-
4 zeigt
ein Blockdiagramm eines Initialisierungsprozesses für einen
Software-Automaten. Alle
Objekte einer Anwendung, die gemäß des Software-Automaten-Paradigmas
erstellt wurde, werden über
die Referenz auf eine Konfigurationsdatei erzeugt. Bei der Initialisierung
wird einem Foreman-Objekt 50 der Name einer speziellen
Konfigurationsdatei 51 bereitgestellt, wie z. B. eine Haupt-Konfigurationsdatei
(MainConfig). Die Konfigurationsdatei spezifiziert und definiert
einen Satz von Objekten der obersten Ebene, die auf Anforderung
durch Foreman 50 von einem Factory-Objekt 52 erzeugt
werden müssen.
Foreman 50 ruft die Datei MainConfig 53 aus einem
Dateisystem oder einer Datenbank 54 ab und übergibt
den Inhalt der Konfigurationsdatei an Factory 52. Jedes
in der Konfigurationsdatei spezifizierte Objekt kann eine oder mehrere
mit ihm verbundene Konfigurationsdateien haben, die weiter spezifizieren,
wie die Objekte konstruiert werden müssen.
-
Foreman 50 übernimmt
die gesamte Verantwortung des Aufbaus der Objekte. Er ist verantwortlich
für die
Konstruktion des Systems als Vorbereitung des Starts. Foreman speichert
die ObjektID und die Objekt-Adresse jedes erzeugten Objektes im
Objekt-Verzeichnis
(objectDictionary). Das Factory-Objekt kann sich bei der Erzeugung
der angeforderten Objekte auf eine Hierarchie von Objekten beziehen. Foreman
konstruiert das System in zwei Schritten:
- 1.
Alle Objekte werden erzeugt und im objectDictionary gespeichert.
Auf dieser Stufe werden die Objekte mit einer ObjectID verbunden.
- 2. Das Verfahren zur Initialisierung des objectDictionary wird
aufgerufen. Das Verzeichnis durchläuft alle Objekte und führt ihr
Initialisierungsverfahren aus. Alle Objekte müssen ObjectID-Referenzen in
physikalische Objekt-Adressen umsetzen.
-
Factory 52 enthält einen
Satz von Factory-Objekten. Jedes Factory-Objekt ist in der Lage, eine
Instanz einer bestimmten Klasse von Objekten zu erzeugen. Mit Bezug
auch auf 5 sind Foreman 50,
Factory 52 und andere Objekte Teil eines Erzeugers dynamischer
Objekte 70. Im Factory-Objekt-Erzeuger wird für jeden
Typ von Objekt, der dynamisch erzeugt werden kann, eine Instanz
eines Factory-Objektes erzeugt. Dynamische Objekte, die vom Erzeuger
dynamischer Objekte 70 erzeugt werden können, enthalten zum Beispiel
Sammlungs-Objekte 72, Thread-Objekte 74, Warteschlangen-Objekte 76,
Zeitgeber-Objekte 78, Zustands-Objekte 80 und
Nachrichten-Objekte 82. Anwendungsprogramme 90 werden
auf den dynamischen Objekten 72–82 aufgebaut, die
vom Erzeuger dynamischer Objekte 70 konstruiert wurden
und nutzen diese dynamischen Objekte zur Ausführung der benötigten Funktionen.
Daher kann Factory 52 für
jede Anwendung nur einmal vorhanden sein, um verschiedene Sätze von
dynamischen Objekten zu erzeugen, die für jede Anwendung geeignet sind.
Die dynamischen Objekte des Anwendungsprogramms werden im Allgemeinen in
zwei Schritten erzeugt.
-
Mit erneutem Bezug auf 4 erzeugt Factory 52 alle
Objekte durch Abruf der Objekt-Kennungen (ObjectID), Objektklassen
und optionalen Objekt-Attribute der Objekt-Klassen, die in Konfigurationsdatei 53 aufgezählt sind.
Factory 52 liefert dann die Adressen der erzeugten Objekte
an Foreman 50 und die Adressen und Objekt-Kennungen der
erzeugten Objekte an ein ObjectDictionary 56, in dem eine
Tabelle oder Datenbank für
deren Speicherung unterhalten wird. Ein Verzeichnis-Objekt 58 in
ObjectDictionary 56 wird dann über seine Initialisierungs-Mitgliederfunktion
angewiesen, alle Objekte zu initialisieren, die in ObjectDictionary 56 gespeichert sind.
Das Verzeichnis 58 durchläuft alle seine gespeicherten
Objekte und ruft deren Mitgliederfunktionen auf. Referenzen zwischen
den erzeugten Objekten werden dann miteinander verbunden. ObjectDictionary 56 ist
ein statisches Objekt, das für
alle dynamisch erzeugten Objekte sichtbar ist. Sein Verzeichnis 56 ordnet
Objekt-Kennungen
der Adresse des entsprechenden Objektes zu. Foreman 50 ist
nur während
der Initialisierungsphase aktiv und ist für die Verwaltung der Erzeugung
der Objekte der obersten Ebene in der übergebenen Konfigurationsdatei
verantwortlich.
-
Wird es auf diese Weise konstruiert,
kann ein Anwendungsprogramm schnell geändert werden, indem die Konfigurationsdateien
geändert
werden, ohne dass der Code neu compiliert oder gelinkt werden muss.
Konfigurationsdateien können
in TCL geschrieben werden, es kann jedoch auch eine Script-Sprache
oder sogar ASCII verwendet werden, um die Liste von Namen der Konfigurationsdateien zu
spezifizieren, in denen die Objekt-Spezifikationen gespeichert sind.
-
6 ist
ein Klassen-Kontext-Diagramm von bestimmten Rahmen-Klassen der Software-Automaten-Architektur. 6 erläutert die Kontext-Beziehung
der Software-Automaten-Klassen,
die im Kontext von einer oder mehreren abstrakten Thread-Klassen 100 ausgeführt werden.
Thread 100 ist eine abstrakte Klasse, die das zentrale
Objekt im Software-Automaten
ist. Eine abstrakte Klasse ist eine Klasse, die eine oder mehrere
rein virtuelle Funktionen hat, die definiert, aber in der abstrakten Klasse
nicht implementiert sind. Daher können Instanzen aus einer abstrakten
Klasse nicht direkt erzeugt werden. Eine abstrakte Klasse wird dazu
verwendet, zusätzliche
Klassen abzuleiten, die Implementationen der rein virtuellen Funktionen
enthalten. Thread 100 empfängt OSMessages (Betriebssystem-Nachrichten) 102 von
einer QueueManager-Instanz 104, wandelt sie in Nachrichten-Objekt-Instanzen 106 um
und sendet sie an eine Instanz FsmMap 108. Message 106 ist
eine abstrakte Klasse, welche die Schnittstelle zur Erlangung der
Kennung einer Nachricht definiert. Die Instanz FsmMap 108 fragt Nachrichten-Instanz 106 nach
ihrer symbolischen Nachrichten-Kennung
ab und setzt sie in die Adresse einer FsmInstance 110 um,
der die Verantwortung für die
Verarbeitung der Nachricht zugewiesen wurde. Eintreffende Automaten-Nachrichten
können
durch ein einziges Objekt FsmInstance 110 oder durch ein FsmCollection-Objekt verarbeitet
werden, das in 5 als
ein Objekt FsmArray 112 gezeigt ist und eine Array-Nachricht 114 empfängt.
-
FsmArray-Objekt 112 fragt
die Automaten-Array-Nachricht 114 nach einer FsmInstance-Kennung
ab, die in eine oder mehrere spezielle FsmInstances (oder Sammlung) 120 umgesetzt wird,
denen die Verantwortung für
die Verarbeitung der Nachricht zugewiesen wird. FsmInstance 120 verwaltet
die Verarbeitung der Nachricht. Jede FsmInstance 120 enthält ihre
aktuelle Zustandskennung und die Adresse des Zustandes 122,
der die Verarbeitung der Nachricht spezifiziert. FsmInstance 120 ruft
die Mitgliederfunktion zur Verarbeitung des Ereignisses des Zustandes
auf. Wenn das Zustandsobjekt 122 eine neue Zustandskennung
zurückgibt, macht
FsmInstance 120 folgendes:
- 1. Aufruf
der aktuellen Mitgliederfunktion zum Verlassen des Zustandes;
- 2. Aufruf der Eintritts-Funktion des nächsten Zustandes; und
- 3. Wiederholung von Schritt 2, wenn die Eintritts-Funktion von
Schritt 2 eine Zustandskennung zurückgibt.
-
Instanzen eines Ereignis-Zustandsobjektes 126 enthalten
ein StateDictionary 128 der Ereignisse, die für diesen
Zustand definiert sind. Die empfangene Automaten-Nachricht wird
nach ihrer symbolischen Nachrichtenkennung abgefragt, die in die
Adresse eines oder mehrerer Ziel-Ereignisse 130 umgesetzt wird.
Ereignis-Zustandsobjekt 126 gibt die Automaten-Nachricht
und das Objekt FsmInstance an Ereignis 130 weiter. Ereignis-Instanz 130 gibt
einen Zeiger auf eine Instanz LogicalState zurück, wenn eine Zustandsänderung
erforderlich ist. Jede Instanz eines Ereignis-Zustandes 126 wird
aus einer StateDictionary-Klasse 128 abgeleitet
und hat daher ebenfalls ein Verzeichnis der logischen Zustände. Die
Klasse StateDictionary 128 verwaltet Sammlungen von Zuständen und
enthält
Mitgliederfunktionen zur Hinzufügung
eines Zustandes zu ihrer Sammlung und zur Umwandlung einer StateID
in die Adresse ihres zugehörigen
Zustandes. Jede Instanz von StateDictionary enthält zwei Verzeichnisse:
initDictionary
enthält
StateID-zu-ObjectID-Paare;
_stateDictionary enthält Zustands-Adressen,
die durch das ObjectDictionary vom
-initDictionary umgesetzt
werden.
-
Ereignis-Zustand 126 setzt
dann den von Ereignis 130 zurückgegebenen LogicalState in
eine Zustandskennung (StateID) um und setzt sie weiterhin in die
Adresse des zugehörigen
Zustandsobjektes 122 um, die an den Aufrufer seiner Mitgliederfunktion zur
Verarbeitung des Ereignisses zurückgegeben wird.
-
Die allgemeinen Parameter der Konfigurationsdatei
für jede
Klasse sind die folgenden:
set ObjectAttributes(0,ObjectClass)
ClassName
set ObjectAttributes(0,ObjectID) ObjectID
set
configFiles(0,fileName) fileNamel.config
set configFiles(1,fileName)
fileName2.config
set ObjectAttributes(0,traceState) DISABLED
-
Exemplarisch erforderliche Parameter
können
das folgende Format haben:
_stateID Initial State Name
set
ClassNameAttributes(0,ClassNameState) StateID
_stateDictionaryID
Adresse des Verzeichnisses zur Umsetzung von StateID-Instanzen
set
ClassNameAttributes(0,FsmStateDictionary)
ObjectID
-
Der oben angegeben ClassName ist
der Name der Klasse, der dort eingesetzt werden muss.
-
7 ist
ein Diagramm, das den logischen Fluss einer OSMessage 102 von
einer QueueManager-Instanz 104 bis zur Verarbeitung durch
ein Ereignis-Objekt 130 weiter erläutert. Eine abgeleitete Klasse
CPThread 140 erzeugt Aufruf-Verarbeitungs-Nachrichten- Instanzen und gibt
sie als Nachrichten-Instanzen zurück. FsmInstance 120 setzt Werte
von Zustandskennungen (StateID), die sie von einer Ereignis-Zustands-Instanz
(die eine vom Zustands-Verzeichnis 128 abgeleitete Klasse
ist) zurück
empfängt,
in die Adresse des damit verbundenen Zustandes 122 um.
Die Automaten-Architektur erlaubt es, wechselnde Automaten-Modelle
für spezielle
Instanzen von FsmInstance auszutauschen, wobei die Sammlung von
Zuständen
sich um nur eine Zustands-Instanz unterscheiden kann.
-
In 8 ist
ein Blockdiagramm eines Beispiels mit mehreren Anwendungen gezeigt.
In einem Anwendungsprogramm zur Verarbeitung von Telekommunikationsverbindungen
kann eine Software-Automaten-Anwendung für einen allgemeinen Umsetzer 140 zur
Umsetzung der Anrufverarbeitung vorhanden sein, der zusammen mit
einer Anzahl von Anruf-Modellen 142 vorhanden ist. Ein
Multi-Anwendungs-Thread-Objekt 144 erzeugt
Nachrichten 146 aus OSMessages 148, die vom QueueManager 104 empfangen
werden. Multi-Anwendungs-Thread 144 leitet die Nachricht
an ein Anwendungs-Steuerungs-Objekt 150 weiter, das die
Nachrichten 146 an die entsprechende Anwendung weiterleitet.
Multi-Anwendungs-Thread 144 erbt seine Daten und Funktionen
von Thread-Objekt-Klasse 100, und Anwendungs-Steuerung 150 erbt
von einer Objektklasse FsmCollection (Mehrfach-FsmInstance-Objekt 120).
-
Demgemäß wurde, um die Funktionalität des Software-Automaten
zu erzielen, ein exemplarischer Satz von Klassen-Hierarchien entwickelt.
Einige dieser Klassen-Hierarchien wurden oben kurz beschrieben und
werden im Folgenden zusammengefasst:
- – Alle empfangenen
Nachrichten werden von einer Nachrichten-Klasse abgeleitet, die
alle Anwendungs-Details vor dem Software-Automaten verbirgt.
- – Es
wird eine Thread-Klasse erzeugt, die eine rein virtuelle Funktion
definiert, um OSMessage-Instanzen in kompatible Nachrichten-Instanzen
umzusetzen.
- – Eine
Klasse FsmMap unterstützt
einzelne Instanzen des endlichen Automaten, sowie Sammlungen von
Instanzen des endlichen Automaten.
- – Eine
Klasse FsmEntity ist die abstrakte Schnittstelle zwischen dem Software-Automaten und Aufruf-Blöcken.
- – Eine
Zustands-Klasse definiert das abstrakte Verhalten für den Eintritt
und das Verlassen eines Zustandes sowie die Verarbeitung eines Ereignisses.
- – Neue
Zustands-Klassen, Verzeichnis-Zustand und konfigurierbarer Zustand
unterstützen
logische Zustandsänderungen.
Der Anwender ist für die
Definition des Satzes logischer Zustandsvariablen und die Umsetzung
vom logischen Zustand auf die physikalische Zustandskennung innerhalb jedes
Zustandes verantwortlich.
- – Die
Ereignis-Klassen-Hierarchie unterstützt die Verarbeitung eines
speziellen Ereignisses für
einen Zustand.
-
Diese Objektklassen werden im Folgenden detaillierter
erläutert.
-
9 zeigt
ein Vererbungs-Diagramm von Objektklassen. Im Software-Automaten stammen alle
Objekte, die durch einen Erzeuger dynamischer Objekte 70 ( 5) aus einer Konfigurationsdatei
erzeugt werden können,
von einer Basisklasse ab, der Objektklasse 170. Da Objekte
während
der Initialisierungsphase des Prozesses (in 4 gezeigt) erzeugt und initialisiert
werden, liefert Objektklasse 170 die Schnittstelle für den Zugriff
auf initialisierte Objekte, die in ObjectDictionary 56 gespeichert
sind (4). Aus der Objekt-Klasse 170 werden
die Zustands-Objekt-Klasse 172, das Objekt FsmEntity 174,
die Ereignis-Objekt-Klasse 176 und die Nachrichten-Objekt-Klasse 178 abgeleitet.
Objekte vom Typ Objekt müssen
die Basis-Implementation der folgenden exemplarischen Verfahren überschreiben:
- 1. init – Auflösung aller
ObjectID-Referenzen in physikalische Objekt-Adressen unter Verwendung
von ObjectDictionary;
- 2. start execution – Durchführung aller
Prozesse nach der Initialisierung, wie z. B. Erzeugung eines Thread;
- 3. string stream – Das
Objekt muss alle seine Daten-Attribute in einem von Menschen lesbaren ASCII-Format
ablegen; und
- 4. get class – Rückgabe einer
String-Instanz, welche die Klasse des Objektes eindeutig kennzeichnet.
-
Objektklasse 170 ist eine
abstrakte Klasse, welche die Schnittstelle für die Objekt-Initialisierung definiert.
Wie oben beschrieben, ist die Initialisierung ein zweistufiger Prozess
der Konstruktion und Auflösung
von Objektadressen. Nach dem Initialisierungsprozess beginnt die
Ausführung.
Es ist die Aufgabe von ObjectDictionary, die Mitgliederfunktion
zur Initialisierung eines Objektes durchzuführen. Die Mitgliederfunktion
zur Initialisierung ist eine virtuelle Funktion, die dazu benutzt
wird, auszulösen,
dass das abgeleitete Objekt sich selbst initialisiert. Das Objekt setzt
alle ObjectID-Referenzen in physikalische Objektadressen um, damit
es direkt auf die Zielobjekte zugreifen kann. Daher muss jedes Objekt,
das sich im ObjectDictionary befinden kann, von einer Objektklasse
Dictionary abgeleitet werden. Da Objektklasse 170 eine
abstrakte Klasse ist, können
keine Instanzen davon erzeugt werden.
-
10 zeigt
ein Klassen-Hierarchie-Diagramm der Objektklasse FsmEntity 174 gemäß einer Ausführung der
vorliegenden Erfindung. Die Klasse FsmEntity 174 verallgemeinert
das Verhalten des Empfangs und der Verarbeitung von Nachrichten durch
Definition einer Mitgliederfunktion processEvent, die eine rein
virtuelle Funktion ist, welche die Schnittstelle für den Empfang
zu verarbeitender Nachrichten definiert. Eine FsmEntity kann ein
einfaches Objekt sein, wie z. B. eine FsmInstance, oder sie kann
eine Sammlung von Einheiten sein, wie z. B. FsmCollection, die unten
beschrieben wird. Instanzen von FsmEntity sind über ihr Attribut -parentEntity mit
einer Eltern-Einheit verbunden.
-
FsmInstance 196 erbt das
Nachrichten-Schnittstellen-Verhalten von FsmEntity 174 und ist
die Basisklasse für
zustandsorientierte Objekte, die eine Anwendung definieren kann,
wie z. B. Anrufblock-Objekte in einer Telekommunikations-Anwendung
zur Verarbeitung von Anrufen. Das grundlegende Objekt in einer Fernsprech-Anwendung
ist der Anrufblock. Er enthält
den aktuellen Zustand des Anrufes für eine spezielle Verbindungsleitung
und bietet Speicherplatz für
die zu sammelnden eintreffenden Ziffern. Die Objektklasse FsmInstance 196 enthält kein
anwendungsspezifisches Verhalten oder Attribute, sondern definiert
stattdessen das allgemeine Verhalten für ein Objekt, das einen Zustand
hat. Anwendungsspezifische Objekte, wie z. B. Anrufblöcke, können aus
der Klasse FsmInstance 196 angeleitet werden. FsmInstance 196 hat
ein Attribut, _state, welches den aktuellen Zustand einer Objekt-Instanz definiert,
und ein weiteres Attribut, _stateMachine, das die Adresse des Automaten
enthält,
der dazu benutzt wird, StateIDs in Zustandsobjekt-Instanzen umzusetzen.
Wenn seine Mitgliederfunktion processEvent aufgerufen wird, wird
die empfangene Nachricht durch die Mitgliederfunktion processEvent
an den Zustand weitergegeben. Diese Mitgliederfunktion gibt einen
Zeiger auf StateID zurück,
wenn ein Zustandswechsel erforderlich ist. FsmInstance gibt dann
eine Anforderung an die Instanz StateMachine aus, um die StateID
in die Adresse des Zustandsobjektes umzuwandeln, ruft zuerst die
Mitgliederfunktion zum Verlassen des Zustandes auf und dann die Eintritts-Funktion des nächsten Zustandes.
FsmInstance enthält
weiterhin eine Mitgliederfunktion setStateID, die eine öffentliche
Funktion ist, welche dazu verwendet wird, die anfängliche
StateID einzustellen, die vom Objekt FsmInstanceFactory aufgerufen
werden muss, bevor die Initialisierungsfunktion aufgerufen wird.
Eine weitere öffentliche
Funktion, setStateDictionaryID, stellt die ObjektID des Zustands-Verzeichnisses
ein, die aufgerufen werden muss, bevor die Initialisierungsfunktion
aufgerufen wird.
-
Die Klasse FsmArrayInstance 198 erbt
von FsmInstance 196 und definiert das Zustandsverarbeitungs-Verhalten
für ein
Array aus FsmInstance. FsmArrayInstance 198 kann dieselben
Mitgliederfunktionen und Attribute haben wie FsmInstance 196.
-
Die Klasse FsmTimedInstance 200 erbt
von FsmArrayInstance 196 und liefert Unterstützung für einen
Zeitgeber, der automatisch beim Eintreten in einen Zustand gestartet oder
gestoppt wird. FsmTimedInstance 200 definiert zwei rein
virtuelle Funktionen, startTimer und stopTimer, um Zeitgeber beim
Eintreten in einen Zustand zu starten, bzw. beim Verlassen eines
Zustandes zu stoppen. FsmTimedInstance 200 enthält weiterhin
eine öffentliche
Funktion, processTimeout, die den Eintrittspunkt für Zeitüberschreitungs-Ereignisse vom Zeitgeber
liefert. Die Mitgliederfunktion processTimeout hat folgenden logischen Ablauf:
- 1. Ausgabe einer Trace-Nachricht, falls freigegeben
- 2. Wenn ein Zustand zurückgegeben
wurde (was anzeigt, dass ein Zustandswechsel bevorsteht), Umwandlung
der StateID des nächsten
Zustandes in eine Adresse des Objektes
- 3. Wenn Trace freigegeben ist, Ausgabe einer Trace-Nachricht
- 4. Verlassen des aktuellen Zustandes
- 5. Wenn Trace freigegeben ist, Ausgabe der Trace-Nachricht
- 6. Eintritt in den nächsten
Zustand
-
Lock 202 ist eine Klasse,
die den Verriegelungs-Mechanismus des Betriebssystems zusammenfasst,
um das Betriebssystem von der Anwendungssoftware zu trennen. Viele
Klassen verwenden Lock 202 als eine Mischangs-Eltern-Klasse.
-
FsmMultipleTimedInstance 204 ist
eine Klasse, die es erlaubt, dass für eine FsmInstance gleichzeitig
mehrere Zeitgeber laufen. FsmMultipleTimedInstance 204 erbt
von FsmTimedInstance 200 und fügt Mitgliederfunktionen für die Hinzufügung eines Zeitgebers
zum zulässigen
Satz von Zeitgebern hinzu, sowie zum Starten und Stoppen eines bestimmten
Zeitgebers. Es liegt in der Verantwortung des Anwendungsprogramms,
die Zeitgeber zu starten und zu stoppen, die in einem Verzeichnis,
_timerMap, gehalten werden, das die Adressen der Zeitgeber im zulässigen Satz
von Zeitgebern enthält.
Anders als der von der Eltern-Klasse FsmTimedInstance definierte Zeitgeber
wird keiner dieser Zeitgeber von den grundlegenden Zustandsklassen
beim Eintritt oder beim Verlassen eines Zustandes automatisch gestartet
oder gestoppt. FsmMultipleTimedInstance 204 enthält eine
Mitgliederfunktion startMultipleTimer, die folgenden logischen Ablauf
hat:
- 1. Holen der Adresse des Zeitgebers aus _timerMap
- 2. Falls der Zeitgeber nicht in _timerMap vorhanden ist, Ausdrucken
einer Fehlermeldung und Rücksprung
- 3. Aktivieren des Zeitgebers
- 4. Rücksprung
-
Auf ähnliche Weise greift eine Mitgliederfunktion
stopMultipleTimer auf _timerMap zu, um die Adresse eines bestimmten
Zeitgebers zu holen, und deaktiviert ihn, wenn sie aufgerufen wird.
Eine Mitgliederfunktion addMultipleTimer kann aufgerufen werden,
um einen Zeitgeber zum Satz von Zeitgebern hinzuzufügen und
_timerMap mit seiner Adresse zu aktualisieren.
-
FsmEntityAllocator 192 ist
eine weitere Klasse, die von FsmEntity 174 erbt. FsmEntityAllocator 192 ist
eine abstrakte Klasse, die das Verhalten für einen Satz aus einer oder
mehreren FsmEntity definiert. Eine rein virtuelle Funktion preProcess
erlaubt es einer abgeleiteten Klasse, eine Verarbeitung auf einer
zugeordneten FsmEntity auszuführen,
bevor sie die Nachricht zur Verarbeitung bekommt. Klassen-Attribute
umfassen eine IdleQueaeID, die auf den Satz nicht zugeordneter FsmEntity
zeigt, die für eine
Zuordnung zur Verfügung
stehen.
-
Auf gleiche Weise erbt die Klasse
FsmDynamicArrayAllocator 194 von FsmEntityAllocator 192 und
definiert weiterhin das Verhalten für die Zuordnung einer FsmInstance
von einem FsmArray. Außerdem
wird eine ungenutzte Warteschlange verwendet, um den Satz nicht
zugeordneter und verfügbarer
FsmInstances zu organisieren.
-
Das Verhalten von Sammlungen von
FsmEntity wird durch eine Klasse FsmCollection 190 definiert,
die das Verhalten eines beliebigen Satzes von FsmEntity abstrahiert.
FsmCollection 190 definiert die Schnittstelle für das Hinzufügen oder
Entfernen von FsmEntity zum oder aus dem Satz. Sammlungs-Klassen
können
ein dynamisches/statisches Attribut haben, wobei sie selbst und
das Kind statisch, sie selbst statisch und das Kind dynamisch oder
sie selbst und das Kind beide dynamisch sein können. Sammlungs-Klassen können bei
der Ereignis-Verarbeitung auch nicht-verriegelnd oder verriegelnd
sein. Weiterhin kann ein Index-Attribut der Sammlungs-Klassen anzeigen,
ob MessageID als Index verwendet wird, oder die Nachricht kann einen Index
enthalten. Sammlungs-Klassen können
auch von dem Typ sein, bei dem ein Verzeichnis für die Erkennung des Kindes
oder ein Array für
die Kinder verwendet wird. Demgemäß kann für eine Sammlungs-Klasse folgende
Bezeichnungs-Konvention verwendet werden:
Fsm<DYNAMIC><LOCK><INDEX><TYPE>
-
FsmCollection enthält eine
Mitgliederfunktion, getFsmEntity, welche die Adresse der Einheit
in der Sammlung zurückgibt,
die für
die Verarbeitung einer Nachricht verantwortlich ist. Eine Mitliederfunktion
processEvent hat folgenden logischen Ablauf:
- 1.
getFsmEntity
- 2. Wenn FsmEntity nicht definiert ist, Leer-Nachricht und Rücksprung
- 3. Aufruf der Mitgliederfunktion processEvent von FsmEntity
- 4. Rücksprung
-
11 ist
ein Klassen-Hierarchie-Diagramm für FsmCollection 190.
Folgt man der oben angegebenen Bezeichnungs-Konvention, ist FsmArray 210 eine
Klasse, die das Verhalten für
ein lineares Array von FsmEntity-Instanzen bereitstellt. Die Anzahl
von Einheiten in der Sammlung oder in dem Satz kann während der
Konstruktionsphase der Initialisierung festgelegt werden. Die FsmEntity-Instanzen
in der Sammlung haben als Index eine ganze Zahl. Mitgliederfunktionen
von FsmArray 210 enthalten Funktionen, die eine Manipulation
des Arrays erlauben. Zum Beispiel kann eine öffentliche Mitgliederfunktion,
createArray, aufgerufen werden, um ein leeres Array zu erzeugen.
Eine öffentliche
Mitgliederfunktion, insertEntity, kann dazu benutzt werden, eine
FsmEntity in das Array einzufügen.
Eine öffentliche
Mitgliederfunktion, getEntityAtIndex, holt die Adresse einer FsmEntity,
und getSize ist eine private Funktion, welche die Größe des Arrays
zurückgibt.
-
Die Mitgliederfunktion init von FsmArray kann
den folgenden logischen Ablauf haben:
- 1. Erzeugen
eines neuen Arrays für
die Speicherung von Objekt-Adressen
- 2. Für
jedes Objekt im Array Aufruf des Verfahrens zur Initialisierung
von Einheiten
- 3. Wenn ein Objekt im Array nicht initialisiert werden konnte,
Rückgabe
einer Fehlermeldung
- 4. Andernfalls Rückgabe
einer Erfolgsmeldung
-
Die benötigten Parameter für die Konfigurationsdatei
können
die Anzahl von Einheiten im Array angeben.
-
LockingArray 212 ist eine
Klasse, die von FsmArray 210 erbt und zur Eltern-FsmArray-Definition eine
Verriegelung zum gegenseitigen Ausschluss hinzufügt. Das Verriegelungs-Verhalten
wird von der Klasse Lock 202 geerbt.
-
Die Klasse FsmDynamic Array 214 erbt
von FsmArray 210 und ändert
ihr Verhalten, um die dynamische Zuordnung von FsmEntity zum Array
zu unterstützen.
FsmDynamicArray 214 überschreibt
die Initialisierungs-Methode von FsmArray, wobei es den Index jedes
Eintrages im Array zur leeren Warteschlange hinzufügt. Instanzen
von FsmDynamic Array 214 wirken nur als Aufbewahrungsort
für die
Array-Elemente. Die Zuordnung von unbenutzten Array-Einheiten wird
von Instanzen von FsmDynamicArrayAllocator 194 durchgeführt (10).
-
Die Klasse FsmMap 220 erbt
von FsmCollection 190 und definiert das Verhalten einer
Sammlung von FsmEntity, die von MessageID indiziert werden. Die
von der Nachricht erhaltene MessageID wird dazu benutzt, ein Abbild
oder Verzeichnis zu indizieren, um an der speziellen FsmEntity zur
Verarbeitung der Nachricht anzukommen. Daher enthalten Mitgliederfunktionen
von FsmMap 220 createDictionary, womit ein Verzeichnis
zur Umsetzung von MessageID auf FsmEntity erzeugt wird, und insertEntity, womit
eine FsmEntity in das erzeugte Verzeichnis eingefügt wird.
Eine Mitgliederfunktion getFsmlnstanceID kann den folgenden logischen
Ablauf haben:
- 1. Holen der MessageID aus der
empfangenen Nachricht
- 2. Holen der Adresse der Ziel-FsmEntity aus dem Verzeichnis
unter Verwendung von MessageID
- 3. Wird die Ziel-FsmEntity nicht gefunden, Ausdruck einer Trace-Nachricht
und Rücksprung
- 4. Andernfalls Rückgabe
der Adresse von FsmEntity
-
Die Klasse LockingMap 222 erbt
von FsmMap 220 und Lock 202, um einen Verriegelungs-Mechanismus zu FsmMap 220 hinzuzufügen.
-
12 ist
ein Kontext-Diagramm, das die Verarbeitung von Nachrichten durch
dynamische Arrays zeigt. Wenn die Mitgliederfunktion processEvent einer
FsmMap-Instanz aufgerufen wird, um eine erste Nachricht zu empfangen
und zu verarbeiten, welche die Zuweisung einer FsmEntity erfordert,
wird sie an eine Instanz von FsmDynamicArrayAllocator 194 geleitet.
FsmDynamicArrayAllocator-Instanz 194 erhält einen
freien Eintrag in das Array und gibt die Nachricht zur Verarbeitung
an die neu zugewiesene Einheit. QueueHead 222 enthält den Index
des nächsten
verfügbaren
Eintrags im Array oder der ungenutzten Warteschlange. Nachfolgende
Nachrichten, die von FsmMap 220 empfangen werden, werden
zu FsmDynamicArray 214 geleitet.
-
13 zeigt
ein Vererbungs-Diagramm von Zustandsklassen. Zustandsklassen definieren
das Verhalten einer FsmInstance an einem bestimmten Punkt der Verarbeitung.
Durch die Technik, Zustände als
Objekte zu definieren, wird diese Logik aus der FsmInstance entfernt,
und im Code werden case/if-Anweisungen beseitigt. Der Zustand als
Objekt ist auch in der Lage, Verhalten zusammenzufassen, das sich
normalerweise in den Ereignis-Funktionen befindet,
die Zustandsänderungen
auslösen.
Die abstrakte Basis-Zustandsklasse 230 definiert das allgemeine
Verhalten für
alle Zustände,
die processEvent, enter und exit sind. Wie oben beschrieben, löst FsmInstance
eine Zustandsänderung
aus, wenn die Adresse einer StateID-Instanz von einem Aufruf der Mitliederfunktion
processEvent zurückgegeben
wird. Sie ruft die Mitgliederfunktion zum Verlassen des aktuellen
Zustandes auf, wandelt die StateID in eine physikalische Objektadresse
um und ruft die Funktion zum Eintritt in den nächsten Zustand auf. Zustandsklasse 230 bietet
die fehlende Implementation von Eintritts- oder Austritts-Funktionen, so dass
abgeleitete Klassen nicht erforderlich sind, um das Eintritts- und
Austritts-Verhalten zu nutzen. Mitgliederfunktionen der Zustandsklasse 230 enthalten
weiterhin getStateID, welche die StateID zurückgibt, setStateID, mit welcher
die StateID geändert
wird, processTimeout, die einen Eintrittpunkt für Zeitüberschreitungs-Ereignisse in den
Zustand bereitstellt.
-
LogicalStateBehavior 234 ist
eine Klasse, die logische Zustandsänderungen unterstützt, um eine
Schnittstelle zu Ereignis-Objekten zu bieten. Sie enthält ein Verzeichnis
definierter LogicalStates, die sie in StateIDs umsetzt. Die Klasse
DictionaryState 232 erbt sowohl von State 230 als
auch von LogicalStateBehavior 234 und liefert die Schnittstelle
zwischen FsmInstance und Ereignis-Objekten. Wie oben beschrieben,
erfordert FsmInstance StateID für Zustandsänderungen
und Event gibt LogicalState für Zustandsänderungen
zurück.
Dictionary State 232 enthält eine rein virtuelle Funktion,
dictionaryProcessEvent, die das Ereignis verarbeitet und einen von Null
verschiedenen Wert von LogicalState zurückgibt, wenn eine Zustandsänderung
erforderlich ist. Eine Mitgliederfunktion processEvent hat folgenden logischen
Ablauf:
- 1. Auffangen aller Ausnahmebedingungen
- 2. Aufruf der Mitgliederfunktion dictionaryProcessEvent
- 3. Umsetzung und Rückgabe
jedes logischen Zustandes, der von dictionaryProcessEvent zurückgegeben
wurde
- 4. Wenn eine Ausnahmebedingung aufgefangen wurde, dann Aufruf
von getErrorState
- 5. Wenn ein Objekt zurückgegeben
wurde, Wiedereinschalten der Ausnahmebedingung
- 6. Andernfalls Rückgabe
der errorState-Adresse
-
Die Klasse MooreBehavior 236 implementiert
das Moore-Zustandsmodell, bei dem die Verarbeitung von Ereignissen
im Zustand durchgeführt wird.
Im Gegensatz dazu wird beim Mealy-Modell die Verarbeitung auf dem Übergang
zwischen den Ereignissen durchgeführt. MooreBehavior 236 enthält die Mitgliederfunktion
enterObject, die von einer abgeleiteten Klasse aufgerufen werden
kann, um die Verarbeitung für
das Eintreten in einen Zustand durchzuführen, die Mitgliederfunktion
exitObject, die von einer abgeleiteten Klasse aufgerufen werden
kann, um die Verarbeitung für
das Verlassen eines Zustandes durchzuführen, die Mitgliederfunktion
addEntryObject, mit der der Wert von ObjectID in den Mitgliederdaten
entryID gesetzt wird, die Mitgliederfunktion addExitObject, mit
der der Wert von ObjectID in den Mitgliederdaten exitID gesetzt
wird, und die Mitgliederfunktion initMooreBehavior, die von einer
abgeleiteten Klasse aufgerufen werden kann, welche die Eintritts-
und Austritts-ObjectIDs in physikalische Objektadressen auflöst.
-
Die Klasse MooreState 234,
die von MooreBehavior 236 erbt, implementiert das Moore-Zustandsmodell
und definiert die Daten-Attribute_enterEvent und _exitEvent, die
in physikalische Objektadressen umgesetzt werden, wenn die Mitgliederfunktion
initMooreBehavior aufgerufen wird.
-
Die Klasse EventDictionaryBehavior 240 liefert
ein Verzeichnis erlaubter Ereignis-Objekte, die durch MessageIDs indiziert
werden. EventDictionaryState 240 enthält eine Mitgliederfunktion
addEvent, die einen Zustand zum Verzeichnis hinzufügt, eine Mitgliederfunktion
getEvent, die eine Diagnose-Schnittstelle zur Überprüfung der Konfiguration des
Verzeichnisses bereitstellt, eine Mitgliederfunktion processMessage,
welche die MessageID aus der empfangenen Nachricht erhält und sie
als verbindenden Index in das Ereignis-Verzeichnis verwendet, um die
Adresse des Ereignis-Objektes zu erhalten, das für die Verarbeitung der Nachricht
verantwortlich ist, und die Mitgliederfunktion initEventDictionary,
welche die ObjektID von Ereignissen im Verzeichnis in physikalische
Adressen auflöst.
Die Mitgliederfunktion processMessage hat zum Beispiel folgenden
logischen Ablauf:
- 1. Holen der MessageID aus
der empfangenen Nachricht
- 2. Wenn MessageID nicht im Ereignis-Verzeichnis enthalten ist,
Senden einer processEvent-Nachricht an defaultHandler und Rückgabe des
logischen Zustandes, der von defaultHandler zurückgegeben wird
- 3. Andernfalls Aufruf der Mitgliederfunktion zur Verarbeitung
des Ereignisses und Rückgabe
des zurückgegebenen
logischen Zustandes
-
Die Mitgliederfunktion initEventDictionary kann
den folgenden logischen Ablauf haben:
- 1. Umsetzung
von defaultHandlerID in ObjectID
- 2. Wenn ein Fehler bei der Umsetzung der Adresse auftritt, Fehlerbearbeitung
und Rücksprung
- 3. Für
jede ObjectID im Ereignis-Verzeichnis Umsetzung der ObjectID in
eine Objekt-Adresse. Wenn
bei der Umsetzung ein Fehler auftritt, Fehlerbearbeitung und Rücksprung,
andernfalls Rückgabe
einer Erfolgsmeldung
-
Die Klasse EventState 238 erbt
sowohl von MooreState 234 als auch von EventDictionaryBehavior 240 und
arbeitet als Dispatcher, um eine Nachricht an das geeignete Ereignis-Objekt
zu leiten. Sie benutzt die Klasse EventDictionaryBehavior 240 als Mischungs-Eltern-Klasse
und enthält
ein Verzeichnis, welches die MessageID einer Nachricht auf ein Ereignis-Objekt
umsetzt. Wenn die MessageID im Verzeichnis nicht gefunden wird,
wird die Nachricht an einen defaultHandler geleitet.
-
TimedState 242 ist eine
Klasse, die von EventState 238 abgeleitet wird und für eine FsmInstance
Zeitgeber-Dienste bereitstellt. Ein Zeitgeber wird beim Eintritt
in den Zustand gestartet und beim Verlassen des Zustandes angehalten.
Die Funktion des Startens und Stoppens des Zeitgebers ist transparent
zu den Methoden enterApplication und exitApplication des Anwenders.
TimedState 242 enthält eine
Initialisierungs-Mitgliederfunktion,
die den folgenden logisehen Ablauf haben kann.
- 1.
Aufruf der Initialisierungs-Mitgliederfunktion der Eltern-Klasse
- 2. Wenn bei der Initialisierung der Eltern-Klasse ein Fehler
auftritt, Abbruch und Rückgabe
des Initialisierungs-Status der Eltern-Klasse
- 3. Umsetzung von _timerInterfaceID in eine physikalische Objektadresse
- 4. Wenn bei der Umsetzung ein Fehler auftritt, Rückgabe des
Fehlers an den Aufrufer, andernfalls Rückgabe einer Erfolgsmeldung
- 5. Umsetzung von timeoutEventID in eine physikalische Objektadresse
- 6. Wenn bei der Umsetzung ein Fehler auftritt, Rückgabe des
Fehlers an den Aufrufer, andernfalls Speicherung der Adresse des
Objektes und Rückgabe
einer Erfolgsmeldung
-
14 ist
ein Vererbungs-Diagramm von Ereignisklassen. Ereignisklassen brechen
die Ereignisverarbeitung in getrennt konfigurierte Objekte vom Zustands-Objekt
auf. Ereignis-Objekte können
von Zustands-Instanzen gemeinsam genutzt werden. Daher spezifizieren
Ereignis-Instanzen keine expliziten Zustands-Objekte für Zustandsübergänge. Stattdessen
geben Sie einen Wert LogicalState zurück, der von dem Zustand in
den entsprechenden Ziel-Zustand umgesetzt wird. Die Basisklasse
Event 260 ist eine abstrakte Klasse, welche die Schnittstelle
zur Verarbeitung eines Ereignisses definiert. Event 260 definiert
eine rein virtuelle Funktion processEvent, die einen von Null verschiedenen
Wert von LogicalState zurückgibt,
um eine Zustandsänderung
anzuzeigen. An die Mitgliederfunktion processEvent wird die Adresse
von FsmInstance geliefert, die empfangene Nachricht und die Adresse
des aktuellen Zustandes.
-
DeterministicEvent 262 ist
eine von Event 260 abgeleitete Klasse und bildet die deterministische
Ereignisbehandlung nach, indem sie jedes Mal, wenn sie die Kontrolle
bekommt, einen konstanten Wert von LogicalState zurückgibt.
Ein deterministisches Ereignis erzwingt auch denselben Zustandsübergang
für einen
Zustand. Eine Mitgliederfunktion, setLogicalState, kann aufgerufen
werden, um LogicalState einen Wert zuzuweisen.
-
DeterministicFunction 264 ist
eine von Event 260 abgeleitete Klasse und bildet auch die
deterministische Ereignisbehandlung nach, indem sie jedes Mal, wenn
sie die Kontrolle bekommt, einen konstanten Wert von LogicalState
zurückgibt.
DeterministicFunction 264 ist DeterministicEvent 262 ähnlich,
definiert aber die Schnittstelle für eine Funktion, die keine
Anzeige einer logischen Zustandsänderung
zurückgibt.
-
Es können zusätzliche Klassen 266 mit
spezialisierten Anwendungen definiert werden, die von der Klasse
Event 260 erben.
-
15 ist
ein Vererbungs-Diagramm von Nachrichtenklassen. Nachrichtenklassen
definieren die Attribute und das Verhalten, das erforderlich ist, um
eine empfangene Nachricht zur Behandlungsroutine für eine FsmInstance,
einen Zustand oder ein Ereignis zu leiten, um die Nachricht zu verarbeiten. Nachrichtenklassen
definieren kein anwendungsspezifisches Verhalten und unterstützen sowohl
dynamische als auch statische Nachrichten. Eine dynamische Nachricht
ist eine Nachricht, die nach Bedarf erzeugt wird und nach der Verarbeitung
freigegeben wird, eine statische Nachricht existiert ständig und enthält keine änderbare
Information. Nachrichtenklassen unterstützen auch Arrays von FsmEntity
und Verzeichnisse oder Abbilder von FsmEntity.
-
Message 270 ist eine abstrakte
Basisklasse für
alle Nachrichten, die in dem Software-Automaten ausgetauscht werden. Message 270 definiert
eine eindeutige symbolische Kennung, MessageID, für jeden
Typ von Nachricht und eine Schnittstelle für ungenutzte Nachrichten. Message 270 kann
eine Mitgliederfunktion getMessageID enthalten, die eine rein virtuelle
Funktion ist, welche die MessageID zurückgibt, die mit einer Objekt-Instanz
verbunden ist; idleYourself, die eine virtuelle Funktion ist, mit
der das Löschen
einer nicht-statischen
Nachricht angefordert werden kann.
-
StaticMessage 272 ist eine
interne Nachricht, die dazu benutzt wird, Nachrichten zwischen Instanzen
des Automaten (FsmInstances) zu senden. Instanzen von StaticMessage
können
benutzt werden, wenn ein einfacher effizienter Signalisierungs-Mechanismus
zwischen FsmInstances gewünscht
wird.
-
MapBehavior 276 ist eine
abstrakte Klasse, die eine Schnittstelle zum Erhalten der symbolischen Referenz
zu einer Nicht-Array-FsmEntity bereitstellt. Eine rein virtuelle
Funktion von MapBehavior, getFsmEntityID, kann von abgeleiteten
Klassen aufgerufen werden, um die Adresse einer String-Instanz zurückzugeben,
die das Ziel der Nachricht symbolisch kennzeichnet.
-
ArrayBehavior 278 ist eine
abstrakte Klasse, die eine Schnittstelle bereitstellt, um den Index
auf eine FsmEntity zu erhalten, der in einem Array von FsmEntity
enthalten ist. Eine rein virtuelle Funktion von ArrayBehavior 278,
getFsmAnay, kann aufgerufen werden, um den Array-Index einer FsmEntity
zu bekommen.
-
ApplicationBehavior 280 ist
eine abstrakte Klasse, die eine Schnittstelle bereitstellt, um den symbolischen
Namen der Anwendung zu erhalten, die das Ziel der Nachricht ist.
Eine rein virtuelle Funktion, getFsmApplicationID, kann verwendet
werden, um die Adresse einer String-Instanz zu bekommen, die das
Ziel der Nachricht symbolisch kennzeichnet.
-
MultiDimensionMessage 274 ist
eine Klasse, die von StaticMessage 272 abgeleitet wird
die Schnittstellen mischt, die von MapBehavior 276, ArrayBehavior 278 und
ApplicationBehavior 280 definiert werden. Sie wird von
den Instanzen FsmArray und FsmMap benötigt, um die FsmEntity innerhalb
ihrer Sammlung zu bestimmen, die das Ziel der Nachricht ist.
-
Weitere anwendungsspezifische Nachrichtenklassen 282,
die von MultiDimensionMessage 274 erben, können in
Zukunft definiert werden.
-
16 ist
ein Kontext-Diagramm der Foundry-Klassen. Die Foundry-Klassen werden
dazu verwendet, Nachrichten zu konstruieren und zu senden, die zwischen
anderen Prozessen oder Objekten innerhalb dieses Prozesses ausgetauscht
werden. Foundy-Objekte werden von Foundry-Factory-Objekten hergestellt
und erfordern daher, dass eine Konfigurationsdatei erstellt wird.
Ein Anwendungsprogramm 300 kann Foundry 302 auffordern,
ein bestimmtes FsmEntity-Objekt herzustellen. Foundry antwortet,
indem es eine Instanz von OutgoingMessageFoundry 306 auffordert,
die Nachricht zu erzeugen. Instanzen von OutgoingMessageFoundry 306 werden
von OutgoingMessageFoundryFactory-Objekten 304 als Reaktion
auf die Anforderung durch Foundry 302 hergestellt. Die
Klasse Foundry 302 ist ein Herstellungszentrum für abgehende
Nachrichten. Sie ist eine Container-Klasse von Objekten des Typs OutgoingMessageFoundry 306.
Eine Mitgliederfunktion, manufacture, wird dazu verwendet, das Foundry-Objekt
zu adressieren, welches für
die Herstellung und Ausgabe einer Nachricht verantwortlich ist.
Die Mitgliederfunktion manufacture sucht das OutgoingMessageFoundry-Objekt,
das für
die Herstellung einer Instanz der von Anwenderprogramm 300 empfangenen
MessageID verantwortlich ist. Im Folgenden wird ein Beispiel für einen
logischen Ablauf von manufacture angegeben:
- 1.
Wenn ein Foundry-Objekt nicht im Verzeichnis der MessageID ist,
Anzeige einer Fehlermeldung und Rückgabe eines Fehlers
- 2. Andernfalls Aufruf der Mitgliederfunktion create des Objektes,
das im Verzeichnis vorhanden ist und Rückgabe des Erzeugungs-Status.
-
Eine weitere Mitgliederfunktion,
addFoundry, wird aufgerufen, um ein OutgoingMessageFoundry-Objekt
zum Verzeichnis hinzuzufügen,
wenn nicht schon ein Eintrag für
die MessageID vorhanden ist. Im Folgenden wird ein Beispiel für einen
logischen Ablauf von addFoundry angegeben:
- 1.
Wenn das Verzeichnis bereits einen Eintrag für die übergebene MessageID hat, dann
Fehler
- 2. Andernfalls Hinzufügung
des übergebenen
Objektes zum Verzeichnis und Rückgabe
einer Erfolgsmeldung
-
17 ist
ein Vererbungs-Diagramm von OutgoingMessageFoundy 306.
OutgoingMessageFoundy 306 ist eine Basisklasse für das in
Foundry 302 gespeicherte Objekt. Objekte des Typs OutgoingMessageFoundy 306 werden
verwendet, um Instanzen von Nachrichten-Objekten zu erzeugen, die aus
der aktuellen FsmEntity-Instanz gesendet werden. Eine Mitgliederfunktion
create liefert die öffentliche
Schnittstelle zur Herstellung einer Instanz einer abgehenden Nachricht.
Create kann zum Beispiel den folgenden logischen Ablauf haben:
- 1. Erzeugung eines leeren Nachrichten-Objektes
- 2. Wenn die Erzeugung einer Nachricht nicht möglich ist,
Rückgabe
einer Fehlermeldung
- 3. Konstruktion einer abgeleiteten Nachricht
- 4. Wenn die Nachricht nicht erzeugt wurde, Rückgabe einer Fehlermeldung 5.
Andernfalls Senden der Nachricht und Rückgabe einer Erfolgsmeldung
-
OutgoingMessageFoundy 306 enthält weiterhin
eine rein virtuelle Funktion, send, um die erzeugte Nachricht an
ihren Zielpunkt zu senden.
-
PonMessageFoundy 308 ist
eine abgeleitete Klasse von OutgoingMessageFoundy 306 und
unterstützt
die Erzeugung von Nachrichten, die aus einer Instanz PonMap 310 gesendet
werden. Wenn das Erzeugungs-Verfahren von PortMessageFoundy 308 aufgerufen
wird, stellt es eine Instanz einer OSMessage her, die über PonMap-Instanz 310 gesendet wird.
Dies kann man im Kontext-Diagramm in 18 sehen.
-
PortMessageFoundy 308 kann
eine Initialisierungs-Mitgliederfunktion enthalten, die folgenden logischen
Ablauf haben kann:
- 1. Aufruf des Eltern-Initialisierungs-Verfahrens
- 2. Wenn der Aufruf des Eltern-Initialisierungs-Verfahrens fehlschlägt, Rückgabe einer
Fehlermeldung
- 3. Wenn objectID des Ports nicht spezifiziert ist, Fehler und
Rückgabe
einer Fehlermeldung
- 4. Holen der Adresse des Pon-Objektes aus dem ObjectDictionary
- 5. Wenn das Objekt nicht im ObjectDictionary gefunden werden
kann, dann Rückgabe
einer Fehlermeldung
- 6. Andernfalls Rückgabe
einer Erfolgsmeldung
-
19 ist
ein Kontext-Diagramm von Befehlsklassen und 20 ist ein Vererbungs-Diagramm von Befehlsklassen.
Befehlsklassen bieten einen Rahmen für eine Benutzerschnittstelle
in den Prozess. Befehls-Objekte fassen das Verhalten zusammen, das
für einen
einzelnen Befehl erforderlich ist. Alle Befehls-Objekte werden von
einer abstrakten Klasse Command 324 abgeleitet. Befehls-Objekte sind
Einzelobjekte, die erzeugt und in einem CommandDictionary 322 untergebracht
werden, bevor main aufgerufen wird. CommandThread 320 empfängt ein
String-Objekt, das den Inhalt eines Befehls enthält. CommandThread 320 ruft
eine Ausführungs-Mitgliederfunktion
von CommandDictionary 322 auf, welche die öffentliche
Schnittstelle ist, die den Befehl analysiert, den Befehls-String
mit einem Kennzeichen versieht (RWCTokenizer) und im Verzeichnis
nachsieht, ob der Befehl darin enthalten ist. Wenn er im Verzeichnis
enthalten ist, führt
sie die Mitgliederfunktion zum Ausführen eines Befehls-Objektes
aus. Eine Mitgliederfunktion von Command 324, execute,
definiert die Schnittstelle für
die Ausführung des
Befehls, der in der Objekt-Instanz zusammengefasst ist.
-
Eine Klasse TraceControlCommand 326 ist eine
von Command 324 abgeleitete Klasse. Eine Ausführungs-Mitgliederfunktion
von TraceControlCommand 326 kann zum Beispiel den folgenden
logischen Ablauf haben:
- 1. Holen der neuen
Trace-Zustands-Option aus dem Befehl
- 2. Wenn ein Trace-Zustand nicht spezifiziert ist, Rückgabe einer
Fehlermeldung
- 3. Umwandlung des Trace-Zustandes in Großbuchstaben
- 4. Wenn der neue Trace-Zustand ENABLE ist, dann Freigabe des
Tracing für
das globale Trace-Objekt
- 5. Andernfalls, wenn der neue Zustand DISABLE ist, dann Sperren
des Tracing für
das globale Trace-Objekt
- 6. Andernfalls Rückgabe
einer Fehlermeldung
-
Eine weitere Mitgliederfunktion von
TraceControlCommand 326 ist stringStream, welche die Schnittstelle
für das
Ablegen des Inhaltes des Befehls in ein String-Objekt definiert.
Da sie als virtuelle Funktion definiert werden kann, wird erwartet,
dass abgeleitete Klassen die Eltern-Implementation überschreiben,
sie rufen die Eltern-Implementation jedoch als Teil ihrer Implementation
auf.
-
Eine von Command 324 abgeleitete
Klasse ist die Klasse TraceObjectCommand 328. TraceObjectCommand 326 fasst
den Anwenderbefehl TraceObject zusammen, um das Verfolgen von Objekten innerhalb
des ObjectDictionary zu steuern. Wenn die von dem Befehl erhaltene
ObjectID ALL ist, wird der Trace-Zustand aller Objekte im ObjectDictionary
als ENABLE oder DISABLE beeinflusst, wie im Befehl spezifiziert.
-
DumpObjectCommand 330 ist
eine von Command 324 abgeleitete Klasse und ist verantwortlich
für die
Ausführung
eines Anwenderbefehls DumpObject.
-
21 ist
ein Kontext-Diagramm für
Zeitgeber-Klassen, und 22 ist
ein Vererbungs-Diagramm für
Zeitgeber-Warteschlangen-Klassen. Die Klasse Timer 350 ist
eine Klasse, die dazu verwendet werden kann, die Erzeugung und das
Ablaufen von Zeitgebern zu steuern. Sie unterhält einen Satz von Zählern, die
von externen Threads einzeln hinzugefügt oder entfernt werden. Timer 350 unterstützt Zeitgeber-Aktivitäten, die
nicht auf Zustands- oder
Ereignis-Zeitüberschreitungen
beschränkt
sind. Timer 350 wurde konstruiert, um die Zeit zu minimieren,
die erforderlich ist, Einträge
einzufügen
und zu entfernen und das Herunterzählen von Zeitgebern zu verwalten,
sowie Zeitüberschreitungen
zu erkennen und zu verarbeiten. Durch Verwendung mehrerer Zeitgeber-Warteschlangen
zur Verringerung der mittleren Länge
jeder Warteschlange wird Effizienz gewonnen. Eine Initialisierungs-Mitgliederfunktion
von Timer 350 erzeugt ein Array 352 von 2n TimerHead-Instanzen 353– 356.
TimerHeads 353–356 sind
durch das Attribut _nextTImerHead miteinander verbunden, um eine
kreisförmige
Liste zu bilden. Das Array 352 von TimerHeads 353-356 wird
dazu benutzt, einen Adressberechnungs-Algorithmus zu implementieren, der
das geringwertigste Bit "n" des gewünschten Zeit-Zählwertes
als Index in das Array 352 verwendet. TimerEntry
361–363 bilden
ein Array oder eine Warteschlange (queue) 360 von Zeitgebern, die
von Timer 350 unterhalten werden. Die Klasse TimerEntry
liefert die Schnittstelle, um die Aktionen zu trennen, die auszuführen sind,
wenn der eingegebene Zeitzähler-Wert
abläuft.
-
Timer 350 enthält eine
Mitgliederfunktion tick, die für
jedes Ticken des Zeitgebers von einer TimerThread-Instanz aufgerufen
wird. Die Mitgliederfunktion tick verriegelt Timer 350 und
prüft den
gerade von Timer 350 adressierten TimerHead, und wenn der
aktuelle TimerHead einen oder mehrere TimerEntry 360 in
seiner Warteschlange hat, dekrementiert tick den Zähler aller
TimerEntries in der Warteschlange, deren Zählerstand größer als
Null ist. TimerEntries mit einem Zählerstand von Null vor dem Dekrementieren
werden entfernt, um die Timeout-Verarbeitung durchzuführen. Die
Mitgliederfunktion processTimeout von TimerScheduler 378 wird aufgerufen,
nachdem die abgelaufene TimerEntry aus der TimerHead-Warteschlange
entfernt wurde. Dann schaltet die Mitgliederfunktion tick auf den nächsten TimerHead
in der kreisförmigen
Liste weiter. Nach 2n Aufrufen von tick
sind alle TimerEntry-Warteschlangen, auf die von allen TimerHeads
gezeigt wird, durchlaufen, dekrementiert und die Timeouts verarbeitet.
-
Timer 350 hat eine Initialisierungs-Mitgliederfunktion,
die folgenden logischen Ablauf haben kann:
- 1.
Aufruf der Initialisierung des Eltern-Zustandes
- 2. Wenn die Initialisierung des Eltern-Zustandes fehlschlägt, Rückgabe des
Eltern-Initialisierungs-Status
- 3. Erzeugen eines Arrays von TimerHead
- 4. Wenn die Erzeugung des Arrays von TimerHead fehlschlägt, Rückgabe einer
Fehlermeldung
- 5. Verbinden der TimerHeads in einer kreisförmigen Liste
- 6. Initialisierung des Attributs currentQueueHead zum Starten
der kreisförmigen
Verkettung
- 7. Rückgabe
einer Erfolgsmeldung
-
Eine Mitgliederfunktion addTimer
von Timer 350 hat zum Beispiel den folgenden logischen
Ablauf:
- 1. Berechnung der Werte von LSB (least
significant bit, geringwertiges Bit) und MSB (most significant bit,
höchstwertiges
Bit) des Zählers
- 2. Verriegeln des Zeitgebers
- 3. Holen der aktuellen TimerHead-Nummer
- 4. Addieren des Zähler-LSB
zur aktuellen TimerHead-Nummer (MOD-Nummer von TimerHeads), um ein
TimerHead zu produzieren, wo TimerEntry hinzugefügt wird
- 5. Speichern des MSB-Wertes in TimerEntry
- 6. Hinzufügen
von TimerEntry an das Ende der TimerHead-Warteschlange
- 7. Entriegeln des Zeitgebers
-
Mit erneutem Bezug auf 22 ist die Klasse QueueEntry 370 die
Basisklassen-Definition
für alle
Objekte, die in einer doppelt verketteten Warteschlange gespeichert
werden können.
Die Klasse QueueEntry 370 enthält viele Methoden zur Manipulation
von oder den Zugriff auf Warteschlangen, wie z. B. getNext, getPrevious,
addNext, addPrevious, removeEntry, idleYourself, usw. CounterQueue 372 ist
eine Klasse, die aus QueueEntry 370 abgeleitet wird und
ist die Basisklasse für
Warteschlangen-Einträge,
die von Timer 350 gehandhabt werden. Die in 22 gezeigten Klassen werden
von Klassen, wie z. B. Timer 350, dynamisch erzeugt und
werden typischerweise nicht direkt aus einer Konfigurationsdatei hergestellt.
Instanzen von CounterQueue 372 enthalten ein Zähler-Attribut,
welches die verbleibende Zeit bestimmt, bevor der Eintrag abläuft oder
die Zeit überschritten
wird. CounterQueue definiert ein Attribut _count als ganzzahligen
Wert und Mitgliederfunktionen für
die Handhabung oder den Zugriff auf den Wert _count. Diese Mitgliederfunktionen
sind setCount, getCount, decCount, subtractCount und increaseCount.
Die Mitgliederfunktion subtractCount ist in der Lage, den Zählerstand
um einen übergebenen
Wert zu verringern, während
decCount den Zählerstand
um eins verringert.
-
Wie oben beschrieben, ist TimerEntry 374 eine
abstrakte Klasse für
Zeitgeber, die von Timer 350 unterhalten werden. TimerEntry 374 leitet
einiges von seinem Verhalten von CouterQueue 372 ab. TimerHead 376 ist
eine abgeleitete Klasse von CouterQueue 372 und Lock 202.
-
TimerScheduler 378 erbt
von TimerEntry 374 und ist verantwortlich für das Hinzufügen einer
ScheduleFsmEvent-Instanz an das Ende einer TimerEntry-Warteschlange,
wenn die Mitgliederfunktion processTimeout aufgerufen wird. Es wird
angenommen, dass Instanzen von TimerScheduler permanent einer speziellen
FSM zugewiesen sind und daher nicht dynamisch erzeugt und zerstört werden.
-
23 ist
ein Vererbungs-Diagramm von Warteschlangen-Objekten. Wie oben beschrieben, definiert
die Klasse QueueEntry 370 die Attribute und das Verhalten,
das erforderlich ist, verkettete Listen von Objekten zu unterhalten.
In 22 gezeigte Zeitgeber-Warteschlangen-Klassen
leiten ihr Warteschlangen-Verhalten von QueueEntry 370 ab.
LockedQueueEntry 372 ist eine Klasse, die eine sich gegenseitig
ausschließende
Verrieglung zu QueueEntry, ihrer Eltern-Klassen-Definition, hinzufügt.
-
ScheduledActivity 373 ist
die Basisklasse für alle
Klassen, die eine planmäßige Verarbeitung
implementieren. Ein Scheduling ist erforderlich, um mehrere Instanzen
von FSMS zu verwalten. Andernfalls ist für jede FSM ein Ausführungs-Thread
erforderlich. Eine Scheduling-Verarbeitung ist ebenfalls wünschenswert,
um den Kontext der Ausführung
aufzubrechen. Bei speziellen Sequenzen von Ereignissen kann der
Stapelspeicher überlaufen,
wenn der Kontext der Ausführung
nicht in getrennte Aktivitäten
aufgebrochen wird. Das Scheduling der Verarbeitung einer ScheduledActivity
ist eine abstrakte Basisklasse und definiert die Mitgliederfunktion
executeActivity, welche die gemeinsame Schnittstelle zur Durchführung der
erforderlichen Verarbeitung ist.
-
ScheduledMessage 375 ist
eine Klasse, die von ScheduledActivity 373 abgeleitet ist
und dazu benutzt werden kann, eine Nachricht zu behandeln, die zur
Verarbeitung bereitgestellt wurde.
-
ScheduledFsmEvent 377 ist
eine Klasse, die von ScheduledActivity 373 abgeleitet wird.
Eine Instanz von ScheduledFsmEvent wird erzeugt, wenn eine Nachricht
für eine
spezielle FsmInstance zu verarbeiten ist. Eine Instanz ScheduledFsmEvent 377 wird
erzeugt, wenn eine FsmInstance eine Nachricht oder ein Ereignis
für eine
andere FsmInstance hat und ein Kontext-Bruch erforderlich ist. Instanzen
von ScheduledFsmEvent werden typischerweise für die interne Kommunikation
in hierarchischen Automaten verwendet. Kontext-Brüche sind
erforderlich für
die Kommunikation zwischen FsmInstances, die Nachrichten in beide
Richtungen senden können.
Nur FsmInstance kann es erlaubt werden, die Mitgliederfunktion processMessage
der angeschlossenen FsmInstance direkt aufzurufen. Die zweite FsmInstance muss
ihre Nachrichten ebenfalls bereitstellen. Andernfalls können Ausführungs-Schleifen
eingenommen werden, durch die der Stapelspeicher überläuft. ScheduledFsmEvent 377 hat
ein Attribut _fsm, das die Adresse der FsmInstance enthält, die
zur Verarbeitung der Nachricht zugewiesen wurde; message, das die
Adresse der zu verarbeitenden Nachrichten-Instanz enthält. Seine Mitgliederfunktion
executeActivity ruft die Mitgliederfunktion processEvent des _fsm-Objektes
auf, um die Nachricht zu verarbeiten.
-
QueueHead 380 leitet sein
Verhalten von QueueEntry 370 ab, und Objekt 170 sowie
Instanzen davon können
benutzt werden, Einträge
in der Reihenfolge FIFO (First In First Out) oder LIFO (Last In First
Out) zu speichern und abzurufen. Sein Attribut _next enthält die Adresse
des ersten Eintrags in der Warteschlange, während _previous die Adresse
des letzten Eintrags in der Warteschlange enthält. Eine Warteschlange ist
leer, wenn der Inhalt von _next und _previous gleich der Adresse
des Warteschlangen-Anfangs (queue head) ist. QueueHead 380 liefert
weiterhin noch andere Mitgliederfunktionen zur Manipulation und
zum Zugriff auf Warteschlangen. LockedQueue 382 ist aus
QueueHead 380 und Locked 202 abgeleitet und fügt eine
sich gegenseitig ausschließende
Verriegelung zur Definition der Klasse QueueHead hinzu.
-
WaitQueue 384 ist eine abstrakte
Klasse, welche die Schnittstelle für das Warten an einer leeren
Warteschlange definiert. WaitQueue 384 kann in Multiprocessing-Umgebungen
verwendet werden, in denen Betriebssystemaufrufe für Kontextverschiebungen
erforderlich sind, oder in Vordergrund-/Hintergrund-Anwendungen,
in denen das Programm eine Schleife durchlaufen kann, wenn die Warteschlange
leer ist. WaitQueue 384 definiert eine rein virtuelle Funktion
zum Warten, die von removeLast und removeFirst aufgerufen werden
kann, wenn die Warteschlange leer ist. Wait sperrt den Prozess oder die
Task in einer Multiprocessing-Umgebung oder kehrt einfach in Vordergrund-
oder Hintergrund-Verarbeitungs-Anwendungen
zurück.
Eine weitere rein virtuelle Funktion, signal, wird von addFirst
und addLast aufgerufen, wenn ein Eintrag zu einer ungenutzten Warteschlange
hinzugefügt
wird. Signal macht die erste gesperrte Task bereit, die auf einen
Eintrag in die Warteschlange wartet.
-
SemaphoreQueue 386 erbt
von WaitQueue 384 und enthält ein Semaphor-Objekt, das
zum Sperren eines Thread verwendet wird, während es darauf wartet, dass
ein Eintrag zur Warteschlange hinzugefügt wird. SemaphoreQueue implementiert
die rein virtuellen Funktionen wait und signal, die von WaitQueue 384 definiert
werden.
-
24 ist
ein Vererbungs-Diagramm für Thread-Klassen.
Die Anwendungs-Plattform
darf dem Anwenderprogramm keine vorher erdachte Thread-Architektur
aufbürden.
Daher werden keine Threads erzeugt, es sei denn, sie sind in den
Anwender-Konfigurationsdateien
spezifiziert. Jeder Thread ist ein hergestelltes Objekt. Thread-Klasse 392 ist
die abstrakte Basisklasse für
alle Objekte vom Typ Thread. Thread-Klasse 392 mischt das
Verhalten von Object 170 und ThreadBehavior 390.
ThreadBehavior 390 enthält
alle Schnittstellen, die erforderlich sind, einen Thread zu starten
und zu stoppen. Da ThreadBehavior eine Mischung ist, kann ihr Verhalten
in Anwendungen wiederverwendet werden, bei denen das von der Anwendungsplattform
bereitgestellte verallgemeinerte Verhalten nicht gewünscht ist.
Thread 392 enthält
die Mitgliederfunktion startExecution, um einen Steuerungs-Thread
für eine
Instanz eines Objektes zu erzeugen, die von Thread abgeleitet ist. Wenn
ein Steuerungs-Thread erzeugt wird, fügt er sein zugehöriges Thread-Objekt zu einem globalen ThreadDictionary
hinzu. Auf alle Threads im ThreadDictionary kann über ihre
ThreadID zugegriffen werden. Eine Steuerung nach Beendigung eines
Thread wird in der Klasse ThreadMonitor 398 unterstützt. Wenn
eine Instanz von ThreadMonitor 398 erzeugt wird, wird der
Thread bei einem Aufruf von thr_join beendet. Wenn ein Thread über den
Aufruf von thr_exit verlassen wird, wird er mit der ThreadID des endenden
Thread aktiviert. Wenn ein Thread-Objekt im ThreadDictionary mit
der ThreadID gespeichert wird, wird seine Mitgliederfunktion threadExit
aufgerufen. Klassen von Thread-Objekten werden im Folgenden detaillierter
beschrieben.
-
MainThread 394 erbt von
Thread 392 und Lock 202 und liefert eine allgemeine
Schnittstelle für das
Erhalten von OSMessages von einem QueueManager 410 und
ihre Umwandlung in Nachrichten und ihre Übergabe an eine stateMachineEntity
zur Verarbeitung, wie in 25 gezeigt.
MainThread 394 definiert eine rein virtuelle Funktion,
von der abgeleitete Klassen implementiert werden müssen, um
OSMessage-Instanzen in einen Typ von Nachricht umzuwandeln. MainThread 394 enthält eine
Mitgliederfunktion threadStart, die folgenden logischen Ablauf haben
kann:
- 1. do forever
- 2. Holen einer OSMessage vom QueueManager
- 3. Wenn beim Holen der OSMessage ein Fehler auftritt, Senden
einer Trace-Nachricht zum Objekt cpTraceAndEvent
- 4. Umwandlung der OSMessage in eine Nachricht (makeMessage)
- 5. Senden von processMessage an stateMachineManager
- 6. end do
-
Die Mitgliederfunktion getMessage
wird im obigen Schritt 2 verwendet, um eine OSMessage von der voreingestellten
Warteschlange PortMap zu empfangen. Die Mitgliederfunktion makeMessage
ist eine rein virtuelle Funktion, welche eine Schnittstelle zur Rückgabe eines
Typs von Nachricht implementiert, wenn eine OSMessage-Instanz übergeben
wird.
-
TimerThread 400 ist eine
andere Klasse, Die von Thread 392 abgeleitet wird. TimerThread 400 ist einer
von zwei Steuerungs-Threads, die für die Ausführung des Timer-Objektes innerhalb
einer UNIX-Programmierumgebung erforderlich sind. Es werden zwei
Threads benutzt, um eine konstante mittlere Rate sicherzustellen,
mit der die Mitgliederfunktion Timer tick ausgeführt wird. TimerThread ist verantwortlich
für die
Signalisierung von SlaveTimerThread 414 mit einem konstanten
Tick-Intervall, wie in 26 gezeigt.
TimerThread 400 enthält
eine einfache Ausführungsschleife,
mit der eine Verzögerung realisiert
wird, indem ein Abfrage-Systemaufruf das zwischen den Timer-Ticks
benötigte
Intervall liefert. Nachdem er aus dem gesperrten Zustand zurückgekehrt
ist, ruft TimerThread die Mitgliederfunktion tick von SlaveTimerThread
auf, bevor er wieder gesperrt wird. SlaveTimerThread 414 ist
der Kontext, unter dem Zeitgeber-Aktualisierungen von Timer ausgeführt werden.
SlaveTimerThread enthält
ein Semaphor-Objekt, das von TimerThread 400 inkrementiert wird,
wenn es die Mitgliederfunktion tick von SlaveTimerThread aufruft.
SlaveTimerThread 414 wird am Semaphor zwischen den Aufrufen
der Mitgliederfunktion tick des Timer 350 suspendiert.
Das Intervall zwischen dem Suspendieren von SlaveTimerThread kann
wegen der zufälligen
Natur der Arbeit, die er intern in Timer 350 auszuführen hat,
nicht kontrolliert werden. Der Zustand des Semaphors stellt jedoch
sicher, dass keine Zeitgeber-Ticks verloren gehen.
-
QueueThread 396 ist eine
Klasse, die von Thread 392 abgeleitet wird, und ist verantwortlich
für den
Empfang von OSMessages von einem auf einer Warteschlange basierenden
Thread oder Prozess 422 und sendet sie über einen Socket an eine Nachrichten-Behandlungsroutine
(Handler) 420 einer nicht residenten Anwendung. Dies ist
in 27 gezeigt.
-
QueueClientThread 402 ist
eine Klasse, die von Thread 392 abgeleitet ist und ist
verantwortlich für
den Empfang von OSMessages von der Nachrichten-Behandlungsroutine 420 einer
nicht residenten Anwendung und sendet sie über einen Socket an eine Anwendungs-Task oder an einen
Prozess, wie in 28 gezeigt.
-
DispatcherThread 404 ist
eine weitere Klasse, die von Thread 394 abgeleitet wird.
DispatcherThread 404 unterstützt die Ausführung von
Arbeiten, die intern im Prozess geplant sind. Zwei Instanzen FsmEntity
können
die Verarbeitung von Nachrichten füreinander planen, indem sie
eine Instanz von ScheduledActivity 374 erzeugen und sie
zu QueueHead 380 hinzufügen, überwacht
von den DispatcherThread-Instanzen. Dies ist in 29 gezeigt. Eine oder mehrere Instanzen
von DispatcherThread 404 kann Instanzen von ScheduledActivity 374 von
einem QueueHead 380 bekommen. Eine Mitgliederfunktion executeActivity
jeder Instanz ScheduledActivity wird aufgerufen, bevor angefordert
wird, dass das Objekt sich selbst in den Ruhezustand versetzt. DispatcherThread 404 wird
dazu benötigt,
den Kontext der Ausführung
für die
Timeout-Verarbeitung und für
Situationen aufzubrechen, welche die Verarbeitung interner Nachrichten
betreffen, die zwischen Objekten in der Anwendung gesendet werden.
Ohne Verwendung von DispatcherThread können Deadlock-Bedingungen auftreten.
-
30 ist
ein Vererbungs-Diagramm für
Trace-Objekt-Klassen. Es werden zwei plattformunabhängige Trace-Klassen
bereitgestellt. Tracer 430 sorgt für ein systemweites Freigeben
oder Sperren des Tracing. Wenn ein Tracer-Objekt im gesperrten Zustand
ist, werden keine Trace-Statements ausgeführt. Der Trace-Zustand kann über Aufrufe
der Mitgliederfunktionen enableTracing und disableTracing geändert werden.
ThrottledTracer 432 wird aus Tracer 430 abgeleitet
und unterstützt
ein dynamisches Drosseln oder Stoppen von Trace-Nachrichten in Überlast-Situationen.
Es definiert Mitgliederfunktionen für die Freigabe, das Sperren,
Starten und Stoppen des Drosselns. 31A und 31B zeigen den Fluss der
Ausführung
bei der Freigabe und beim Sperren von Trace-Zuständen. Die 32A bis 32C zeigen
den Fluss der Ausführung
in den Zuständen mit
gesperrtem Drosseln, inaktivem Drosseln und aktiviertem Drosseln.
-
33 ist
ein Vererbungs-Diagramm von Trace-Objekt-Klassen. Der Satz von Trace-Objekten fasst
die Daten zusammen, die in einer Trace-Operation ausgedruckt werden
müssen.
TraceObject 460 ist die Basisklasse und definiert die Schnittstelle
für die
Ausgabe der Trace-Daten an einen Trace-Strom des Betriebssystems.
StateTraceObject 464 ist eine Klasse, die von TraceObject 460 abgeleitet
wird und fasst Trace-Nachrichten zusammen, die auszudrucken sind,
um Zustandsänderungen
anzuzeigen.
-
34 ist
ein Vererbungs-Diagramm von StateFactory-Klassen. Factory-Objekte
sind verantwortlich für
die Erzeugung einer Instanz einer bestimmten Klasse. Jede Instanz
einer Klasse, die aus einer Konfigurationsdatei erzeugt werden kann,
wird durch ein Factory-Objekt
erzeugt. Auf Factory-Objekte wird über das globale Factory-Objekt
Bezug genommen. Es wird eine statische Instanz jedes Typs von Factory-Objekt
erzeugt und zu Factory hinzugefügt,
bevor in main eingetreten wird. Alle Factory-Objekte werden von
der abstrakten Klasse ObjectFactory 490 abgeleitet. ObjectFactory 490 definiert
die Schnittstelle für
die Erzeugung eines Objektes einer bestimmten Klasse. Seine Mitgliederfunktion,
create, wird von Factory aufgerufen, um eine Instanz herzustellen.
An die Mitgliederfunktion create wird der Name der Konfigurationsdatei übergeben,
welche die Werte aller von dem Objekt benötigten Attribute definiert.
Die Mitgliederfunktion create ruft die rein virtuelle Funktion createObject
auf, um eine leere Instanz des Objektes zu erzeugen, und ruft dann
die virtuelle Funktion constructDerivedObject auf, um die Objekt-Attribute
zu konfigurieren, wie in der Konfigurationsdatei spezifiziert.
-
StateFactory 492 ist eine
von ObjectFactory 490 abgeleitete Klasse. StateFactory 492 ist
eine abstrakte Factory-Klasse zur Erzeugung von Zustands-Instanzen.
StateFactory konfiguriert die Zustands-Instanzen mit der StateID,
die es aus der Konfigurationsdatei erhält. Eine Mitgliederfunktion constructDerivedObject
kann den folgenden logischen Ablauf haben:
- 1.
Aufruf der Eltern-Klasse constructDerivedObject
- 2. Wenn die Konstruktion der Eltern-Klasse fehlschlägt, Rückgabe der
Objektadresse Null
- 3. Holen der StateID aus der Konfigurationsdatei
- 4. Wenn eine StateID nicht geholt werden kann, Ausgabe einer
Fehlermeldung, Löschen
des Objektes und Rückgabe
der Objektadresse Null
- 5. Speichern von StateID in der neuen Zustands-Instanz
- 6. Rückgabe
der Adresse der neuen Zustands-Instanz
-
DictionaryStateFactory 494 ist
eine abstrakte Factory-Klasse zur Erzeugung von DictionaryState-Instanzen
und erbt sowohl von StateFactory 492 als auch von LogicalStateBehaviorFactory 496.
DictionaryState enthält
Abbildungen von LogicalStates auf StateIDs. Eine Mitgliederfunktion
constructDerivedObject von DictionaryStateFactory kann den folgenden
logischen Ablauf haben:
- 1. Aufruf der Eltern-Klasse
constructDerivedObject
- 2. Wenn die Konstruktion der Eltern-Klasse fehlschlägt, Rückgabe der
Objektadresse Null
- 3. Holen der Anzahl der Elemente im Verzeichnis aus der Konfigurationsdatei
- 4. Wenn beim Holen der Anzahl der Elemente ein Fehler auftritt,
Löschen
des Objektes und Rücksprung
- 5. Für
die Anzahl der Elemente in der Konfigurationsdatei Ausführen von:
- 6. Holen des LogicalState aus der Konfigurationsdatei
- 7. Wenn beim Holen des LogicalState ein Fehler auftritt, Ausgabe
einer Fehlermeldung, Löschen des
Objektes und Rücksprung
- 8. Holen der StateID aus der Konfigurationsdatei
- 9. Wenn beim Holen der StateID ein Fehler auftritt, Ausgabe
einer Fehlermeldung, Löschen
des Objektes und Rücksprung
- 10. Hinzufügen
des Paares LogicalState und StateID zum objectDictionary
- 11. Wenn beim Hinzufügen
ein Fehler auftritt, Löschen
des Objektes und Rückgabe
von Null
- 12. Ende der Ausführung
- 13. Rückgabe
der Objekt-Instanz
-
MooreStateFactory 498 ist
eine von DictionaryStateFactory 494 abgeleitete Klasse
und erzeugt Instanzen von MooreState aus einer Konfigurationsdatei.
Ihre Mitgliederfunktion constructDerivedObject ruft die Eltern-Methode
constructDerivedObject auf, um das Objekt zu erzeugen, und erhält eine
ObjectID von der Konfigurationsdatei, um sie in dem erzeugten Objekt
zu speichern.
-
EventStateFactory 500 erbt
von MooreStateFactory 498 und erzeugt Instanzen von EventState aus
einer Konfigurationsdatei. Ihre Mitgliederfunktion constructDerivedObject
kann den folgenden logischen Ablauf haben:
- 1.
Aufruf der Eltern-Klasse constructDerivedObject
- 2. Wenn die Konstruktion der Eltern-Klasse fehlschlägt, Rückgabe der
Objektadresse Null
- 3. Für
jedes Ereignis-Objekt in der Konfigurationsdatei Ausführung von:
- 4. Holen der MessageID aus der Konfigurationsdatei
- 5. Wenn beim Holen der MessageID ein Fehler auftritt, Ausgabe
einer Fehlermeldung, Löschen des
Objektes und Rücksprung
- 6. Holen der ObjectID aus der Konfigurationsdatei
- 7. Wenn beim Holen der ObjectID ein Fehler auftritt, Ausgabe
einer Fehlermeldung, Löschen
des Objektes und Rücksprung
- 8. Hinzufügen
des Paares LogicalState und StateID zum Ereignis-objectDictionary
- 9. Wenn beim Hinzufügen
ein Fehler auftritt, Ausgabe einer Fehlermeldung, Löschen des
Objektes und Rückgabe
der Objektadresse Null
- 10. Ende der Ausführung
- 11. Rückgabe
der Objektadresse
-
TimedStateFactory 502 ist
eine Klasse, die aus EventStateFactory 500 abgeleitet wird.
TimedStateFactory erzeugt Instanzen von TimedState aus einer Konfigurationsdatei.
-
35 ist
ein Vererbungs-Diagramm von EventFactory-Objekten. EventFactory 510 ist
eine abstrakte Klasse zur Erzeugung von Ereignis-Instanzen. EventFactory 510 definiert
die Schnittstelle zur Erzeugung einer Instanz einer Klasse in den
Ereignisklassen. DeterministicEventFactory 512 ist eine Factory-Klasse
zur Erzeugung von Instanzen von DeterministicEvents. DeterministicFunctionFactory 514 ist
eine Factory-Klasse zur Erzeugung von Instanzen von DeterministicFunctions.
Sowohl DeterministicEventFactory 512 als auch DeterministicFunctionFactory 514 haben
die Mitgliederfunktionen constructDerivedObject, welche die Eltern-Klasse constructDerivedObject
zur Erzeugung des Objektes aufrufen, den LogicalState aus einer
Konfigurationsdatei holen und den LogicalState im erzeugten Objekt
speichern. Weitere Klassen 516 können in Zukunft definiert werden.
-
36 ist
ein Vererbungs-Diagramm von FsmEntity-Factory-Klassen. FsmEntityFactory 530 ist
eine abstrakte Factory-Klasse zur Erzeugung von FsmEntity-Instanzen. FsmEntityFactory 530 definiert die
Schnittstelle zur Erzeugung einer Instanz einer Klasse in der FsmEntity-Familie.
FsmCollectionFactory 532 erbt von FsmEntityFactory 530 und
ist verantwortlich für
die Erzeugung von Instanzen von FsmCollection-Objekten. FsmArrayFactory 534 erbt von
FsmCollectionFactory 532 und ist verantwortlich für die Erzeugung
von Instanzen von FsmArray-Objekten. Ihre Mitgliederfunktion constructDerivedObject
kann den folgenden logischen Ablauf haben:
- 1.
Aufruf der Eltern-Klasse constructDerivedObject
- 2. Wenn die Konstruktion der Eltern-Klasse fehlschlägt, Rückgabe der
Objektadresse Null
- 3. Holen der Anzahl der Elemente im Array
- 4. Wenn ein Fehler auftritt, Ausgabe einer Fehlermeldung, Löschen des
Objektes und Rückgabe der
Objektadresse Null
- 5. Erzeugen eines leeren Arrays
- 6. Wenn beim Erzeugen des Arrays ein Fehler auftritt, Ausgabe
einer Fehlermeldung, Löschen des
Objektes und Rückgabe
der Objektadresse Null
- 7. Für
jedes Element im Array Ausführung
von:
- 8. Holen des Namens der Konfigurationsdatei für das Element
aus der Konfigurationsdatei
- 9. Wenn beim Holen des Namens der Konfigurationsdatei ein Fehler
auftritt, Ausgabe einer Fehlermeldung, Löschen des Objektes und Rückgabe der
Objektadresse Null
- 10. Anforderung an Factory, eine Instanz des Objektes zu erzeugen,
das in der Konfigurationsdatei angegeben ist.
- 11. Wenn beim Erzeugen ein Fehler auftritt, Rückgabe der
Objektadresse Null
- 12. Speichern der Adresse des Element-Objektes im Array
- 13. Ende der Ausführung
- 14. Rückgabe
der Array-Objektadresse
-
FsmHugeArrayFactory 538 ist
ebenfalls eine Klasse, die von FsmCollectionFactory 532 abgeleitet wird.
FsmHugeArrayFactory stellt die Schnittstellendefinition für alle FsmHugeArray-Objekte
zur Verfügung,
die entweder direkt oder indirekt aus FsmHugeArrayFactory abgeleitet
werden. FsmHugeArrayFactory definiert die Schnittstellen, die erforderlich sind,
die von FsmHugeArray definierten Attribute aus einer Konfigurationsdatei
zu erzeugen. Ihre Mitgliederfunktion constructDerivedObject kann
den folgenden logischen Ablauf haben:
- 1. Aufruf
der Eltern-Klasse constructDerivedObject
- 2. Zuerst Erzeugung der in der Basisklasse definierten Attribute
- 3. Wenn die Objektadresse Null zurückgegeben wird, Rückgabe der
Objektadresse Null
- 4. Wenn bei der Erzeugung der Basisklasse ein Fehler auftritt,
Rücksprung
- 5. Holen der Anzahl der Einheiten im Array
- 6. Holen des Namens der Konfigurationsdatei, die zur Erzeugung
einer FsmInstance benutzt wurde
- 7. Wenn beim Holen des Namens der Konfigurationsdatei ein Fehler
auftritt, Ausgabe einer Fehlermeldung, Löschen des teilweise erzeugten
Objektes und Rücksprung
- 8. Erzeugen eines leeren Arrays
- 9. Wenn beim Erzeugen des Arrays innerhalb des Objektes ein
Fehler auftritt, Ausgab einer Fehlermeldung, Löschen des teilweise erzeugten
Objektes und Rücksprung
- 10. Für
jede Einheit im Array Ausführung
von:
- 11. Herstellung einer Instanz der Einheit
- 12. Wenn beim Herstellen ein Fehler auftritt, Löschen des
teilweise erzeugten Array-Objektes und
Rücksprung
- 13. Hinzufügen
des Objektes zum Array
- 14. Wenn beim Hinzufügen
einer Einheit zum Array ein Fehler auftritt, Löschen des teilweise erzeugten
Arrays und Rücksprung
- 15. Ende der Ausführung
- 16. Rückgabe
der Array-Adresse
-
FsmMapFactory 542 erbt von
FsmCollectionFactory 532 und ist eine Klasse, die Instanzen von
FsmMap erzeugt und die Adresse des Objektes zurückgibt. LockingArrayFactory 536 erbt
von FsmArrayFactory 534 und erzeugt Instanzen von LockingArray.
FsmDynamicArrayFactory 540 erbt von FsmHugeArrayFactory 538 und
erzeugt Instanzen von FsmDynamicArray. LockingMapFactory 544 erbt von
FsmMapFactory 542 und erzeugt Instanzen von LockingMap.
-
FsmEntityAllocatorFactory 550 erbt
von FsmEntityFactory 530 und erzeugt Instanzen von FsmEntityAllocator
aus einer Konfigurationsdatei. Ihre Mitgliederfunktion constructDerivedObject
kann den folgenden logischen Ablauf haben:
- 1.
Aufruf der Eltern-Klasse constructDerivedObject
- 2. Zuerst Erzeugung der in der Basisklasse definierten Attribute
- 3. Wenn die Objektadresse Null zurückgegeben wird, Rückgabe der
Objektadresse Null
- 4. Wenn bei der Erzeugung der Basisklasse ein Fehler auftritt,
Rücksprung
- 5. Holen der ObjectID der ungenutzten Warteschlange aus der
Konfigurationsdatei
- 6. Wenn beim Holen der ObjectID ein Fehler auftritt, Ausgabe
einer Fehlermeldung, Löschen
des Objektes und Rücksprung
- 7. Speichern der objectID im Objekt
-
FsmDynamicArrayAllocatorFactory 552 erbt von
FsmEntityAllocatorFactory 550 und erzeugt Instanzen von
FsmDynamicArrayAllocator aus einer Konfigurationsdatei. FsmInstanceFactory 554 erbt von
FsmEntityFactory 530 und erzeugt Instanzen von FsmInstance,
indem StateIDs aus der Konfigurationsdatei geholt werden. FsmTimedInstanceFactory 556 erbt
von FsmInstanceFactory 554 und erzeugt Instanzen von FsmTimedInstance.
-
37 ist
ein Vererbungs-Diagramm von ThreadFactory-Klassen. ThreadFactory 570 erbt
sowohl von ObjectFactory 490 als auch ThreadBehaviorFactory 572 und
erzeugt Instanzen von Thread aus einer Konfigurationsdatei. ThreadBehaviorFactory 572 enthält eine
Mitgliederfunktion constructDerivedObject, die den folgenden logischen
Ablauf haben kann:
- 1. Holen des Thread-Namens
- 2. Wenn auf das Element nicht zugegriffen werden kann, Ausdruck
einer Fehlermeldung, Löschen
des Objektes, Rücksprung
- 3. Speichern des Thread-Namens im Objekt
- 4. Holen des Attributes STACK SIZE aus der Konfigurationsdatei
- 5. Wenn STACK_SIZE spezifiziert ist, Umwandlung von STACK_SIZE
in einen ganzzahligen Wert
- 6. Wenn bei der Umwandlung ein Fehler auftritt, Ausdruck einer
Fehlermeldung
- 7. Holen des Attributes THREAD_PRIORITY aus der Konfigurationsdatei
- 8. Wenn THREAD_PRIORITY spezifiziert ist, Umwandlung von THREAD_PRIORITY
in eine ganze Zahl
- 9. Wenn bei der Umwandlung ein Fehler auftritt, Ausdruck einer
Fehlermeldung
- 10. Holen des Attributes BOUND_STATE aus der Konfigurationsdatei
- 11. Wenn THREAD_PRIORITY spezifiziert ist und der Wert TRUE
oder FALSE ist, dann neuen Wert im Objekt speichern, andernfalls
Ausdruck einer Fehlermeldung und Rücksprung
- 12. Holen des Attributes REAL_TIME_STATE aus der Konfigurationsdatei
- 13. Wenn REAL_TIME_STATE spezifiziert ist, Umwandlung in eine
ganze Zahl
- 14. Wenn bei der Umwandlung ein Fehler auftritt, Ausdruck einer
Fehlermeldung
- 15. Holen des Attributes TIME_SHARE_STATE aus der Konfigurationsdatei
- 16. Wenn TIME_SHARE_STATE spezifiziert ist, Umwandlung in eine
ganze Zahl
- 17. Wenn bei der Umwandlung ein Fehler auftritt, Ausdruck einer
Fehlermeldung
-
MainThreadFactory 574 erbt
von ThreadFactory 570 und erzeugt Instanzen von MainThread aus
einer Konfigurationsdatei. Ihre Mitgliederfunktion constructDerivedObject
kann den folgenden logischen Ablauf haben:
- 1.
Aufruf der Eltern-Klasse constructDerivedObject
- 2. Erzeugung der in der Basisklasse definierten Attribute
- 3. Wenn die Objektadresse Null zurückgegeben wird, Rückgabe der
Objektadresse Null
- 4. Holen der QueueManagerID aus der Konfigurationsdatei
- 5. Wenn beim Holen der QueueManagerID ein Fehler auftritt, Löschen des
Objektes und Rücksprung
- 6. Speichern der objectID im Objekt
- 7. Holen der FsmEntity ID aus der Konfigurationsdatei
- 8. Wenn beim Holen der FsmEntity ID ein Fehler auftritt, Löschen des
Objektes und Rücksprung
- 9. Speichern der objectID im Objekt
-
QueueThreadFactory 576 erbt
von ThreadFactory 570 und erzeugt Instanzen von QueueThread aus
einer Konfigurationsdatei. Ihre Mitgliederfunktion constructDerivedObject
kann den folgenden logischen Ablauf haben:
- 1.
Aufruf der Eltern-Klasse constructDerivedObject
- 2. Erzeugung der in der Basisklasse definierten Attribute
- 3. Wenn die Objektadresse Null zurückgegeben wird, Rückgabe der
Objektadresse Null
- 4. Holen der MessageHandler ID aus der Konfigurationsdatei
- 5. Wenn beim Holen der MessageHandler ID ein Fehler auftritt,
Löschen
des Objektes und Rücksprung
- 6. Speichern der objectID im Objekt
-
ThreadMonitorFactory 578 erbt
ebenfalls von ThreadFactory 570 und erzeugt Instanzen von ThreadMonitor
aus einer Konfigurationsdatei. TimerThreadFactory 580 erbt
von ThreadFactory 570 und erzeugt Instanzen von TimerThread
aus einer Konfigurationsdatei. Ihre Mitgliederfunktion constructDerivedObject
kann den folgenden logischen Ablauf haben:
- 1.
Aufruf der Eltern-Klasse constructDerivedObject
- 2. Erzeugung der in der Basisklasse definierten Attribute
- 3. Wenn die Objektadresse Null zurückgegeben wird, Rückgabe der
Objektadresse Null
- 4. Holen der Timer ID aus der Konfigurationsdatei
- 5. Wenn beim Holen der Timer ID ein Fehler auftritt, Löschen des
Objektes und Rücksprung
- 6. Speichern der objectID im Objekt
- 7. Holen des Zeitgeber-Aktivierungsintervalls aus der Konfigurationsdatei
- 8. Wenn ein Fehler auftritt, Löschen des Objektes und Rücksprung
-
QueueClientThreadFactory 582 erbt
von ThreadFactory 570 und erzeugt Instanzen von QueueClientThread
aus einer Konfigurationsdatei. Ihre Mitgliederfunktion constructDertvedObject
benutzt ebenfalls die Eltern-Mitgliederfunktion constructDertvedObject,
um das Objekt zu erzeugen, holt die MessageHandler ID aus der Konfigurationsdatei
und speichert die ObjectID im Objekt. DispatcherThreadFactory 584 erbt
von ThreadFactory 570 und erzeugt Instanzen von DispatcherThread
aus einer Konfigurationsdatei. Ihre Mitgliederfunktion constructDertvedObject
holt die Aktivitäts-Warteschlangen-ID
aus der Konfigurationsdatei und speichert die ObjectID im Objekt.
-
38 ist
ein Vererbungs-Diagramm der Factory-Objekte QueueHead. QueueHeadFactory 600 erbt
von ObjectFactory 490 und erzeugt Instanzen von QueueHead
aus einer Konfigurationsdatei. LockedQueueFactory 602 erbt
von QueueHeadFactory 600 und erzeugt Instanzen von LockedQueue aus
einer Konfigurationsdatei. WaitQueueFactory 604 erbt von
LockedQueueFactory 602 und erzeugt Instanzen von WaitQueue
aus einer Konfigurationsdatei. SemaphoreQueueFactory 606 erbt
von WaitQueueFactory 604 und erzeugt Instanzen von SemaphoreQueue
aus einer Konfigurationsdatei. Alle QueueHead-Factory-Objekte haben Mitgliederfunktion
constructDerivedObject, die Eltern-Methoden constructDerivedObject
aufrufen, Attribute konstruieren, die in der Basisklasse definiert
sind, und eine Objektadresse Null zurückgeben, wenn von dem Konstruktionsschritt
eine Objektadresse Null zurückgegeben
wird.
-
39 ist
ein Vererbungs-Diagramm der Factory-Klassen OutgoingMessageFoundry.
OutgoingMessageFoundryFactory 610 ist eine Basisklasse,
die Instanzen von OutgoingMessageFoundry aus einer Konfigurationsdatei
erzeugt. Ihre Mitgliederfunktion constructDerivedObject kann den
folgenden logischen Ablauf haben:
- 1. Aufruf
der Eltern-Klasse constructDerivedObject
- 2. Erzeugung der in der Basisklasse definierten Attribute
- 3. Wenn die Objektadresse Null zurückgegeben wird, Rückgabe der
Objektadresse Null
- 4. Holen der MessageID aus der Konfigurationsdatei
- 5. Wenn beim Holen der MessageID ein Fehler auftritt, Anzeige
einer Fehlermeldung, Löschen des
Objektes und Rücksprung
- 6. Speichern der objectID im Objekt
- 7. Rückgabe
der Adresse des Objektes, wie es so weit konstruiert wurde
-
PortMessageFoundryFactory 612 erbt
von OutgoingMessageFoundryFactory 610 und erzeugt Instanzen
von PortMessageFoundry aus einer Konfigurationsdatei. Ihre Mitgliederfunktion
constructDerivedObject kann den folgenden logischen Ablauf haben:
- 1. Aufruf der Eltern-Klasse constructDerivedObject
- 2. Erzeugung der in der Basisklasse definierten Attribute
- 3. Wenn die Objektadresse Null zurückgegeben wird, Rückgabe der
Objektadresse Null
- 4. Holen der Port-Verzeichnis-ID aus der Konfigurationsdatei
- 5. Wenn beim Holen der Port-Verzeichnis-ID ein Fehler auftritt,
Löschen
des Objektes und Rücksprung
- 6. Speichern der objectID im Objekt
- 7. Holen des Warteschlangen-Namens aus der Konfigurationsdatei
- 8. Wenn beim Holen des Warteschlangen-Namens ein Fehler auftritt,
Löschen
des Objektes und Rücksprung
- 9. Speichern des Warteschlangen-Namens im Objekt
-
Obwohl die vorliegende Erfindung
und ihre Vorteile detailliert beschrieben wurden, muss deutlich verstanden
werden, dass verschiedene Änderungen und
Abwandlungen, Ersetzungen und Veränderungen darin durchgeführt werden
können,
ohne vom Geist und Umfang der Erfindung abzuweichen, wie in den
beigefügten
Ansprüchen
definiert.