Lade Inhalt...

Framework für Zustandsorientierte Programmierung

Einsatz bei der Implementierung eines Service-Containers

©2007 Diplomarbeit 107 Seiten

Zusammenfassung

Inhaltsangabe:Zusammenfassung:
Diese Ausarbeitung beschreibt ein Framework zur Unterstützung der Zustandsorientierten Programmierung. Mit Zustandsorientierter Programmierung ist hier ein Programmierparadigma gemeint, das Variablen und deren Zustände in den Mittelpunkt stellt. Die Variablen werden funktional in Beziehung gesetzt. Ändert sich der Zustand einer Variablen, so werden die davon abhängenden Variablen angepasst.
Die Zustandsorientierung kann auf der Objektorientierung basieren. Genau dies ist beim hier beschriebenen Framework (im Folgenden auch Zustandsframework genannt) der Fall. Das Zustandsframework ist in der objektorientierten Programmiersprache C# entwickelt. Es umfasst hauptsächlich sog. Zustandsklassen und erlaubt eine Zustandsorientierte Programmierung, indem Attribute von Klassen durch jene Zustandsklassen gekapselt sind. Die Zustandsklassen fungieren gewissermaßen als Container für Attribute und kontrollieren deren Zugriff, insbesondere deren Manipulationen.
Mitarbeiter (Employee) haben eine Arbeitsleistung (performance). Deren Chef (Boss) wacht über ihre durchschnittliche Arbeitsleistung (staffPerformance). Sinkt diese unter 98%, so werden ein paar Mitarbeiter entlassen. Die beiden Performance-Attribute sind eigentlich vom Typ double, werden aber durch eine sog. Einfache Zustandsklasse (State) bzw. eine Aggregierte Zustandsklasse (AggregateState) gekapselt. Im Code-Listing nicht abgebildet ist die Konfiguration der entsprechenden Zustandsobjekte. Insbesondere die Aggregierten Zustandsobjekte müssen durch eine Aggregatsfunktion zur Durchschnittbildung parametrisiert werden und die zugehörigen Einfachen Zustandsobjekte müssen als Kind-Zustände definiert werden. Darüber hinaus ist die Methode PerformanceChanged() als sog. Transitions-Listener für staffPerformance zu definieren. Ändert sich also die durchschnittliche Arbeitsleistung der Belegschaft bzw. findet diesbezüglich ein Zustandsübergang bzw. eine Transition statt, so wird PerformanceChanged aufgerufen.
Unter Verwendung des Zustandsframeworks lassen sich Attribute durch deklarative Programmierung funktional miteinander in Verbindung bringen, Zustandsübergänge lassen sich verfolgen und, wie später noch ersichtlich wird, lassen sich vom Zustandsobjekt vorgesehene Zustandsübergänge sogar blockieren. Letzteres bedeutet, dass der Client bei Transitionen die Möglichkeit hat, entsprechende Aktivitäten durchzuführen. Sind diese nicht erfolgreich, so kann der Client bestimmen, […]

Leseprobe

Inhaltsverzeichnis


Christian Silberbauer
Framework für Zustandsorientierte Programmierung
Einsatz bei der Implementierung eines Service-Containers
ISBN: 978-3-8366-0686-8
Druck Diplomica® Verlag GmbH, Hamburg, 2008
Zugl. Fachhochschule Regensburg, Regensburg, Deutschland, Diplomarbeit, 2007
Dieses Werk ist urheberrechtlich geschützt. Die dadurch begründeten Rechte,
insbesondere die der Übersetzung, des Nachdrucks, des Vortrags, der Entnahme von
Abbildungen und Tabellen, der Funksendung, der Mikroverfilmung oder der
Vervielfältigung auf anderen Wegen und der Speicherung in Datenverarbeitungsanlagen,
bleiben, auch bei nur auszugsweiser Verwertung, vorbehalten. Eine Vervielfältigung
dieses Werkes oder von Teilen dieses Werkes ist auch im Einzelfall nur in den Grenzen
der gesetzlichen Bestimmungen des Urheberrechtsgesetzes der Bundesrepublik
Deutschland in der jeweils geltenden Fassung zulässig. Sie ist grundsätzlich
vergütungspflichtig. Zuwiderhandlungen unterliegen den Strafbestimmungen des
Urheberrechtes.
Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in
diesem Werk berechtigt auch ohne besondere Kennzeichnung nicht zu der Annahme,
dass solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebung als frei
zu betrachten wären und daher von jedermann benutzt werden dürften.
Die Informationen in diesem Werk wurden mit Sorgfalt erarbeitet. Dennoch können
Fehler nicht vollständig ausgeschlossen werden, und die Diplomarbeiten Agentur, die
Autoren oder Übersetzer übernehmen keine juristische Verantwortung oder irgendeine
Haftung für evtl. verbliebene fehlerhafte Angaben und deren Folgen.
© Diplomica Verlag GmbH
http://www.diplom.de, Hamburg 2008
Printed in Germany

Vorwort
Object-oriented software development requires that individual
developers have unscheduled critical masses of time in
which they can think, innovate, and develop, and meet
informally with other team members as necessary to discuss
detailed technical issues. The management team must plan
for this unstructured time.
Grady Booch, Object-Oriented Analysis and Design

Inhaltsverzeichnis
1.
Einleitung ...6
2.
Grundlegende Begriffsdefinitionen ...10
2.1. Zustand ... 10
2.2. Framework ... 11
2.3. Design Patterns ... 12
3.
Das SDS-Projekt ...14
3.1. SDS Container... 14
3.2. Zustände von SDS Components ... 15
3.3. Zustände von Services ... 18
3.4. Abhängigkeiten zu verschiedenen Komponentenzuständen ... 18
4.
Motivation...19
5.
Konzeption ...20
5.1. Modell eines Zustandsobjekts ... 20
5.2. Transitionsalgorithmus ... 22
5.3. Elementare Arten von Zustandsobjekten... 26
5.3.1. Einfache Zustandsobjekte... 27
5.3.2. Aggregierte Zustandsobjekte ... 28
5.3.3. Maskierte Zustandsobjekte ... 28
5.3.4. Geschaltete Zustandsobjekte ... 29
5.3.5. Strebsame Zustandsobjekte ... 30
5.4. Zusammengesetzte Arten von Zustandsobjekten... 34
5.4.1. Kombinierte Zustandsobjekte ... 35
5.4.2. Integrierte Strebsame Zustandsobjekte ... 36
5.4.3. Gemeinsame IS-Zustandsobjekte... 47
6.
Entwurf ...49
6.1. Klasse StateBase (Grundversion) ... 50
6.2. Klasse State ... 59
6.3. Klasse AggregateState... 61
6.4. Klasse MaskedState... 69
6.5. Klasse SwitchedState... 71

6.6. Klasse StrivingState ... 72
6.7. Klassen ComboState, ISState, SharedISState und CompositeState... 73
6.8. Klasse MaskPool für ISState ... 77
6.9. TransitionMode und ActivityHandler für StateBase ... 79
7.
Anwendung im SDS Container ...84
7.1. ComponentManager... 84
7.2. ServiceManager ... 88
7.3. Beispielszenarien für den LifecylceState ... 89
8.
Mögliche Erweiterungen ...94
8.1. Ein weiteres Zustandsobjekt: Das Funktions-ZO... 94
8.2. Konfiguration der Zustandsobjekte mittels Annotations und XML ... 96
9.
Die Zustandsorientierte Programmierung ...101
Stichwortverzeichnis ...104
Literaturverzeichnis ...106

- 6 -
1. Einleitung
Die Zustandsorientierung und das Zustandsframework
Diese
Ausarbeitung
beschreibt
ein
Framework
zur
Unterstützung
der
Zustandsorientierten Programmierung. Mit Zustandsorientierter Programmierung ist
hier ein Programmierparadigma gemeint, das Variablen und deren Zustände in den
Mittelpunkt stellt. Die Variablen werden funktional in Beziehung gesetzt. Ändert sich
der Zustand einer Variablen, so werden die davon abhängenden Variablen
angepasst.
Die Zustandsorientierung kann auf der Objektorientierung basieren. Genau dies ist
beim hier beschriebenen Framework (im Folgenden auch Zustandsframework
genannt) der Fall. Das Zustandsframework ist in der objektorientierten
Programmiersprache C# entwickelt. Es umfasst hauptsächlich sog. Zustandsklassen
und erlaubt eine Zustandsorientierte Programmierung, indem Attribute von Klassen
durch jene Zustandsklassen gekapselt sind. Die Zustandsklassen fungieren
gewissermaßen als Container für Attribute und kontrollieren deren Zugriff,
insbesondere deren Manipulationen. Hierzu ein einfaches Beispiel:
class
Boss
{
AggregateState
<
double
>
staffPerformance;
void
PerformanceChanged()
{
if
(staffPerformance < 0.98)
FireSomeEmployees();
}
}
class
Employee
{
State
<
double
> performance;
void
Work() { ... }
}
Mitarbeiter (Employee) haben eine Arbeitsleistung (performance). Deren Chef
(Boss) wacht über ihre durchschnittliche Arbeitsleistung (staffPerformance).
Sinkt diese unter 98%, so werden ein paar Mitarbeiter entlassen
1
. Die beiden
Performance-Attribute sind eigentlich vom Typ double, werden aber durch eine sog.
Einfache Zustandsklasse (State) bzw. eine Aggregierte Zustandsklasse
(AggregateState) gekapselt. Im Code-Listing nicht abgebildet ist die Konfiguration
1
Dieser Chef ist zwar einfach gestrickt, dafür aber berechenbar.

- 7 -
der
entsprechenden
Zustandsobjekte.
Insbesondere
die
Aggregierten
Zustandsobjekte müssen durch eine Aggregatsfunktion zur Durchschnittbildung
parametrisiert werden und die zugehörigen Einfachen Zustandsobjekte müssen als
Kind-Zustände
definiert
werden.
Darüber
hinaus
ist
die
Methode
PerformanceChanged()
als sog. Transitions-Listener für staffPerformance zu
definieren. Ändert sich also die durchschnittliche Arbeitsleistung der Belegschaft bzw.
findet diesbezüglich ein Zustandsübergang bzw. eine Transition statt, so wird
PerformanceChanged()
aufgerufen.
Unter Verwendung des Zustandsframeworks lassen sich Attribute durch deklarative
Programmierung funktional miteinander in Verbindung bringen, Zustandsübergänge
lassen sich verfolgen und, wie später noch ersichtlich wird, lassen sich vom
Zustandsobjekt vorgesehene Zustandsübergänge sogar blockieren. Letzteres
bedeutet, dass der Client bei Transitionen die Möglichkeit hat, entsprechende
Aktivitäten durchzuführen. Sind diese nicht erfolgreich, so kann der Client
bestimmen, dass das Zustandsobjekt in seinem alten Zustand verharrt.
Alles in Allem ist das Zustandsframework ein hilfreiches Werkzeug, um
Zusammenhänge zwischen Attributen einfach herzustellen und damit eine
zustandorientierte Sichtweise in der Programmierung zu fördern.
Der Kontext
Entstanden ist das Framework in Folge einer Beschäftigung des Autors bei Siemens
Corporate Research in Princeton in den USA. Dort wird ein Verteiltes System
entwickelt. Der Service-Container des Systems hat ein komplexes Lifecycle-
Management für seine Komponenten zu realisieren. Entsprechend ist die
Ausrichtung des Zustandsframeworks. Seine Zustandsklassen sind nach den
Anforderungen des Service-Containers von Siemens entworfen und sind daher keine
allgemeine
Sammlung
von
Zustandsklassen
für
Zustandsorientierte
Programmierung. Dennoch sind vor allem die primitiveren Zustandsklassen recht
universell einsetzbar. Außerdem ist eine Erweiterung des Frameworks um weitere
Zustandsklassen sehr einfach möglich.

- 8 -
Das Flaggschiff: Integrierte Strebsame Zustandsobjekte
Der Schwerpunkt dieser Ausarbeitung bei der Definition von Zustandsklassen liegt in
der Herleitung von Strebsamen Zustandsobjekten und den darauf basierenden
Integrierten Strebsamen Zustandsobjekten. Letztere werden verwendet, um die
Zustände der Komponenten in ihrem Lebenszyklus zu steuern. Die Bezeichnung
strebsam rührt daher, dass durch einen sog. angestrebten Zustand festgelegt
werden kann, welcher Zustand für das Zustandsobjekt wünschenswert wäre.
Strebsame
Zustandsobjekte
haben
aber
Abhängigkeiten
zu
anderen
Zustandsobjekten ­ sog. Restriktive Zustandsobjekte ­, die entsprechende
Zustandsübergänge verhindern können. Ob der angestrebte Zustand zum
tatsächlichen Zustand wird, hängt also davon ab, ob die restriktiven Zustandsobjekte
dies zulassen. Die Bezeichnung integriert meint, dass es sich um ein Netz von
gleichartigen Zustandsobjekten handelt, die sich gegenseitig beeinflussen.
Zum Beispiel beim Service-Container von Siemens haben Komponenten
nacheinander die Zustände Deployed, Created, Initialized und Active, dann ist die
Komponente hochgefahren und bereit für ihre Verwendung. Im Übrigen wird aus
technischer Sicht das entsprechende Attribut als Enumeration abgebildet. Mit jedem
Übergang zwischen zweier dieser Zustände sind notwendige Aktivitäten verbunden,
die jeweils erfolglos durchgeführt werden können und daraufhin das Hochfahren der
Komponente ggf. abgebrochen werden muss. Zudem gilt, dass Komponenten von
anderen Komponenten abhängig sein können und beim Hochfahren sichergestellt
sein muss, dass eine Komponente erst Active wird, bevor ihre abhängige
Komponente Active werden kann. Indes können andere Transitionen unabhängig
von den Komponenten-Abhängigkeiten passieren. Und dieser Service-Container hat
eine weitere Anforderung: Zwar muss eine Komponente beim Hochfahren u.U.
darauf warten Active zu werden, bis ihre Abhängigkeiten Active sind, hingegen darf
eine Komponente beim Herunterfahren nicht blockiert werden. Das bedeutet, dass
Komponenten ihre abhängigen Komponenten ggf. zwingen müssen auf Initialized
herunterzufahren, sodass sie selbst zum Herunterfahren im Stande sind.
Insgesamt also eine komplexe Anforderung an eine Zustandsklasse. Hier ist
besonders ersichtlich, dass eine Auslagerung solcher Funktionalitäten in
Zustandsklassen sinnvoll ist, statt diese direkt in jene Klassen zu implementieren, in

- 9 -
denen sie gebraucht werden. Denn diese haben i.d.R. andere Dinge zu erledigen
und würden sonst unnötig überladen werden. Die Integrierte Strebsame
Zustandsklasse ist modular implementiert. Des Weiteren kann sie durch eine
überschaubare Schnittstelle einfach verwendet werden.
Der Aufbau der Diplomarbeit
In der vorliegenden Ausarbeitung werden zunächst in Kapitel 2 Grundbegriffe wie
Zustand und Framework diskutiert, bevor im Kapitel 3 das Verteilte System von
Siemens vorgestellt wird. Insbesondere wird dabei auf den Service-Container und
dessen
Lifecycle-Management
eingegangen,
denn
dies
soll
durch
das
Zustandsframework letztlich realisiert werden. Kapitel 4 schafft dann aus Sicht des
Service-Containers die Motivation für die Entwicklung des Zustandsframeworks. Im
folgenden Kapitel wird dieses auf konzeptioneller Ebene vorgestellt. Erst wird auf das
grundlegende Modell eines Zustandsobjektes eingegangen, dann werden die
einzelnen Arten von Zustandsobjekten vorgestellt. Kapitel 6 behandelt die
Implementierung des Frameworks. Für ein gutes Verständnis wird Bezug zu
angewendeten Design Patterns genommen, sowie zu Programmierprinzipien, vor
allem objektorientierter Natur. Anschließend wird die Programmierung des Service-
Containers unter Anwendung der Zustandsklassen gezeigt. Und zum Abschluss
beschreibt Kapitel 8 mögliche Erweiterungen des Frameworks, die insbesondere auf
ein allgemeineres Einsatzgebiet abzielen, bis dann Kapitel 9 mit der Einordnung des
beschriebenen Frameworks in das Paradigma der Zustandsorientierung die Arbeit
abrundet.

- 10 -
2. Grundlegende Begriffsdefinitionen
2.1. Zustand
Nach Grady Booch ist ein Zustand eines Objekts wie folgt definiert
2
:
The state of an object represents the cumulative results of its behavior.
Helmut Balzert hat eine technischere, mehr auf die Objektorientierte Programmierung
bezogene Definition
3
:
Der Zustand (state) eines Objekts wird durch seine Attributwerte bzw. Daten und die
jeweiligen Verbindungen zu anderen Objekten bestimmt.
Darüber hinaus definiert er den Begriff Verhalten folgendermaßen:
Das Verhalten (behavior) eines Objekts wird durch seine Menge von Operationen
beschrieben.
In der OOP werden Programme mithilfe von Klassen strukturiert. Klassen bestehen
aus Attributen und aus Methoden. In Rahmen der UML spricht man meist von
Operationen, wobei eine Operation genau genommen die Spezifikation einer
Methode darstellt
4
. Die Methoden einer Klasse dienen dem Zugriff auf deren
Attribute. Im Idealfall greifen nur die Methoden einer Klasse auf deren Attribute zu.
Dadurch werden die Attribute durch die zugehörigen Methoden gekapselt. Sie stellen
die Integrität ihrer Attribute sicher. Konkrete Ausprägungen von Klassen heißen
Objekte. Sie wiederum besitzen Attributwerte und weisen ein Verhalten auf. Das
Verhalten wird durch die Methoden beschrieben. Die Attributwerte eines Objekts
definieren dessen Zustand.
Werden durch einen Methodenaufruf Attributwerte eines Objekts verändert, so ändert
sich also der Zustand eines Objekts. Ein Zustandsübergang bzw. eine sog.
Transition findet statt.
2
Grady Booch, 1993, Object-Oriented Analysis and Design, S. 200
3
Helmut Balzert, 2000, Lehrbuch der Software-Technik, S. 156
4
Vgl. Hitz et al., 2005, UML@Work, S. 37

- 11 -
Zustände und Zustandsübergänge können durch sog. Zustandsautomaten
beschrieben werden. In der UML erfolgt dessen grafische Darstellung durch UML
Zustandsdiagramme. Sie können sich auf unterschiedlichen Abstraktionsniveaus
befinden. Das denkbar feingranularste Zustandsdiagramm würde für jede
Konstellation von Attributwerten einer Klasse einen eigenen Zustand benennen. So
ein Diagramm wäre in den allermeisten Fällen völlig unübersichtlich und unsinnig.
Die in einem Zustandsdiagramm dargestellten Zustände vertreten i.d.R. Mengen von
Attributwerten und nur wenn zwischen verschiedenen Mengen ein Übergang
stattfindet, ist tatsächlich die Rede von einem Zustandsübergang.
(Abstrakte) Zustände werden manchmal in Anwendungen überwacht. Dabei
übernehmen sog. Manager-Objekte die Überwachung bzw. das Management
anderer Objekte. Beispielsweise bei Containern in Verteilten System ist es üblich,
dass ein Komponenten-Manager die Überwachung einer Komponente übernimmt. Er
verfügt dazu über Attribute, die den Zustand der jeweiligen Komponente auf einem
bestimmten Abstraktionsniveau ausdrücken. Entsprechende Attributwerte werden
hier als Explizite Zustände bezeichnet. Sie befinden sich in eigens definierten
Attributen,
um
abstrakte
Zustände
zu
kennzeichnen.
Im
Rahmen
der
Komponentenverwaltung wäre dies z.B. ein Fehlerzustand oder ein Lifecycle-
Zustand. Typischerweise werden explizite Zustände durch Enumerationen
abgebildet.
2.2. Framework
Diese Ausarbeitung befasst sich mit einem Framework für eine zustandsorientierte
Programmierung. Bei einem Framework handelt es sich um eine wieder verwendbare
Teilanwendung, die spezialisiert werden kann, um maßgeschneiderte Anwendungen
zu erstellen
5
.
Es handelt sich also um ein Gerüst von Klassen, bei dem die Aspekte
Wiederverwendbarkeit und Erweiterbarkeit betont sind.
Im Gegensatz zu Klassenbibliotheken sind Frameworks jeweils auf eine Familie
verwandter Anwendungen bezogen. Klassenbibliotheken sind da weniger
bereichsspezifisch. Des Weiteren sind Frameworks aktiv und Klassenbibliotheken
passiv, was heißt, dass Frameworks den Kontrollfluss in der Anwendung steuern und
5
Vgl. Bernd Brügge, Allen Dutoit, 2004, Objektorientierte Softwaretechnik, S. 364

- 12 -
Klassenbibliotheken das nicht tun
6
. Die Klassen eines Frameworks sind auch viel
stärker miteinander gekoppelt, als dies bei Klassenbibliotheken der Fall ist. Die
meisten Klassen einer Klassenbibliothek besitzen überhaupt keine Bindung
untereinander.
2.3. Design Patterns
Design Patterns (Entwurfsmuster) in der Objektorientierten Programmierung wurden
erstmals 1995 von der sog. Gang of Four (GoF) katalogisiert und in einem Buch
veröffentlicht. Sie definieren darin Design Patterns wie folgt
7
:
[
] design patterns [
] are descriptions of communicating objects and classes that
are customized to solve a general design problem in a particular context.
Design Patterns besitzen demnach eine bestimmte Granularität. Sie beschreiben
weder ganze Subsysteme, noch die Interna einer Klasse. Ihr Abstraktionsniveau liegt
dazwischen.
Generell die Idee, Muster zu verwenden, geht auf den Architekten Christopher
Alexander zurück. Er beschreibt in seinen Büchern eine Vielzahl von Mustern, die in
der Architektur ihre Anwendung finden. Den Begriff des Musters definiert er
folgendermaßen
8
:
Each pattern describes a problem which occurs over and over again in our
environment, and then describes the core of the solution to that problem, in such a
way that you can use this solution a million times over, without ever doing it the same
way twice.
Die inzwischen gängige
9
Definition lautet:
Ein Muster ist eine Lösung eines Problems in einem bestimmten Kontext.
Die GoF beschreibt Design Patterns auf einheitliche Art und Weise. Jedes ihrer
Musterbeschreibungen ist folgendermaßen untergliedert:
6
Vgl. Bernd Brügge, Allen Dutoit, 2004, Objektorientierte Softwaretechnik, S. 366
7
Gamma et al., 1995, Design Patterns, S. 3
8
Alexander et al., 1977, A Pattern Language
9
Vgl. Eric Freeman, Elisabeth Freeman, Entwurfsmuster von Kopf bis Fuß, 2006, S. 579

- 13 -
- Pattern Name and Classification
- Intent
- Also Known As
- Motivation
- Applicability
- Structure
- Participants
- Collaborations
- Consequences
- Implementation
- Sample Code
- Known Uses
- Related Patterns
Ohne hier auf Details eingehen zu wollen, lässt es allein die Aufstellung der
Überschriften innerhalb einer einzelnen Entwurfsmusterbeschreibung erahnen, wie
ausführlich die Darstellung ist.
In dieser Ausarbeitung werden speziell in Kapitel 6, in dem der Entwurf des
Frameworks beschrieben ist, die verwendeten Patterns erwähnt und deren Absicht
(Intent) nach der GoF wiedergegeben. Weiterführende Erläuterungen, warum gerade
dieses Design Pattern und kein anderer Entwurf im Framework gewählt wurde,
werden unterlassen. Stattdessen sei auf die GoF verwiesen, die in ihren
umfangreichen Ausarbeitungen über Design Patterns die Begründungen liefern.
Mittlerweile gibt es eine ganze Reihe von Pattern-Büchern im OO-Umfeld, welche
sich mitunter nicht nur mit Entwurfsmustern, sondern auch mit den grobgranulareren
Architekturmustern auseinandersetzen. Falls es für den Leser als hilfreich erachtet
wird, wird auch auf Patterns verwiesen, die über die 23 Ur-Muster der GoF
hinausgehen.
Der Grund, warum bei den Beschreibungen der Klassen des Frameworks überhaupt
auf die jeweils angewendeten Design Patterns verwiesen wird, ist folgender:
Vorausgesetzt der Leser besitzt ausreichend Kenntnisse über die entsprechenden
Muster, so kann der Entwurf des Framework erheblich leichter vermittelt werden. Die
Kommunikation über die Konzepte des Entwurfs wird einfacher.

- 14 -
3. Das SDS-Projekt
Das
Siemens
Distributed
System
(SDS)
10
ist
ein
Siemens
Softwareentwicklungsprojekt,
um
eine
einheitliche
Kommunikationsplattform
anzubieten. Es ist ein Verteiltes System mit zwei
11
Kernkomponenten, nämlich dem
sog. SDS Communication Framework (CF) und dem SDS Service Container
(Container).
Das
SDS
Communication
Framework
bietet
eine
nachrichtenbasierte
Kommunikationsinfrastruktur sowohl für plattformunabhängige als auch größtenteils
sprachunabhängige
Interprozesskommunikation.
Um
mit
beliebigen
Programmiersprachen Dienste für SDS entwickeln zu können, muss jeweils ein
sprachspezifischer Adapter angeboten werden. Derzeit existieren Adapter für C++,
Java und C#.
Der SDS Service Container verwaltet SDS Services und SDS Shared Components.
Hauptsächlich realisiert er deren Lifecycle-Management und publiziert ihre Zustände.
3.1. SDS Container
Aus technischer Sicht verwaltet ein Container SDS Services und SDS Components.
Üblicherweise besteht ein Service aus mehreren Components. Der Service dient also
zur Gruppierung von Komponenten. Allerdings kann eine Komponente auch stand-
alone sein. Damit ist sie nicht Teil eines Services. In einem solchen Fall spricht man
von einer sog. Shared Component.
Komponenten können voneinander abhängig sein. Service-interne Komponenten
können zum einen von Komponenten abhängig sein, die sich im selben Service
befinden, zum anderen können sie von Shared Components ­ also von
alleinstehenden Komponenten ­ abhängig sein. Demgegenüber können Shared
Components nur abhängig von anderen Shared Components sein.
10
Name geändert
11
Offiziell gehört noch eine dritte Komponente zu den SDS-Kernkomponenten, nämlich ein
Persistenzdienst. Der wird hier aber nicht weiter beschrieben.

- 15 -
Wie bereits erwähnt verwaltet der Container Services und Komponenten. Für diesen
Zweck verwendet er ein Objekt vom Typ ComponentManager für jede einzelne
Komponente und entsprechend wird ein Service von einem sog. ServiceManager
überwacht.
3.2. Zustände von SDS Components
Ein ComponentManager hat im Allgemeinen drei (explizite) Komponentenzustände,
nämlich Lifecycle State, Error State und Availability Indicator. Nachfolgend werden
diese Zustandstypen vorgestellt.
12
Lifecycle State
Deployed
Created
Initialized
Active
Der ComponentManager verwaltet den Lifecycle State einer Komponente. Mögliche
Zustände sind Deployed, Created, Initialized und Active.
12
Die Zustandstypen werden nicht vollständig beschrieben; nur insoweit sie hier relevant sind.
/ Create
/ SetParameter,
Initialize
[Dependents < Active]
/ Deactivate
/ Uninitialize
[Dependencies = Active]
/ SetDependency, Activate

- 16 -
Jede Komponente ist durch eine XML-Konfiguration beschrieben. Wenn
entsprechende Konfigurationsdaten vorhanden sind, ist eine Komponente Deployed.
Jede Komponente, die Deployed ist, kann gestartet werden.
Der erste Schritt des Start-Prozesses einer Komponente ist es, ihre Assembly (z.B.
eine dll) zu laden und das Komponentenobjekt anschließend zu instanziieren. Falls
das einwandfrei funktioniert, erhält die Komponente den Zustand Created.
Anschließend sind typischerweise zwei Aktionen notwendig. Erstens kann die XML-
Konfiguration Konfigurationsparameter für eine Komponente beinhalten (einfache
Key-Value-Paare). Diese müssen in der Komponenteninstanz gesetzt werden. Und
zweitens ruft der ComponentManager über ein Komponenten-Interface die Methode
Initialize()
auf. Dies erlaubt der Komponente initialisierende Arbeiten
durchzuführen. Beide Aktionen müssen erfolgreich bewältigt werden, um die
Komponente in den Zustand Initialized zu überführen.
Nun der finale Schritt. Eine Komponente kann Abhängigkeiten zu anderen
Komponenten haben, um deren Dienste in Anspruch zu nehmen. Zunächst
verwendet der ComponentManager SetDependency(), um alle referenzierten
Komponenten zu installieren. Die Komponenten werden mittels Dependency
Injection
13
untereinander bekannt gemacht ­ genau genommen durch Interface
Injection. Danach wird die Activate()-Methode der Komponente aufgerufen. Es
können nur Abhängigkeiten zu Komponenten gesetzt werden, die selbst bereits
aktiviert sind. Es ist also wichtig, die einzelnen Komponenten in der richtigen
Reihenfolge zu aktivieren. Der letzte Zustand einer Komponente wird als Active
bezeichnet.
Um eine aktive Komponente herunterzufahren ruft der ComponentManager, analog
zum Start-Prozess, die Deactivate()-Methode der Komponente auf. Das
Deaktivieren einer Komponente ist nur möglich, wenn keine weiteren aktiven
Komponenten von dieser abhängig sind. Das bedeutet wiederum, die Reihenfolge in
welcher Komponenten z.B. innerhalb eines Services deaktiviert werden, muss
sinnvoll definiert sein. Eine erfolgreich deaktivierte Komponente befindet sich sodann
im Zustand Initialized.
13
Siehe Martin Fowler, 2004, http://martinfowler.com/articles/injection.html

- 17 -
Während des Stopp-Prozesses einer initialisierten Komponente ruft der
ComponentManager
von seiner Komponente die Methode Uninitialize() auf.
Dieser Schritt ist stets unabhängig von anderen Komponenten. Anschließend ist die
Komponente wieder Created.
Dann geht die Komponente zurück in den Zustand Deployed, wo der Stopp-Prozess
schließlich endet.
Error State
Es gibt lediglich zwei verschiedene Ausprägungen von Error State: NoError und
Failed. NoError bedeutet eine Komponente ist funktionsfähig und Failed
kennzeichnet eine Komponente als fehlerhaft.
Eine Komponente kann in jedem einzelnen Lifecycle State Failed sein. Z.B. bedeutet
beim Hochfahren die Kombination aus dem Lifecycle State Deployed und dem Error
State Failed, dass der Erzeugungsprozess fehlgeschlagen ist, weil beispielsweise die
DLL der Komponente nicht verfügbar war. Die Kombination aus dem Lifecycle State
Created und dem Error State Failed bedeutet, der Initialisierungsprozess schlug fehl
usw. usf.
Availability Indicator
Eine Komponente kann ihren Grad von Verfügbarkeit selbst spezifizieren. Der sog.
Availability Indicator ist durch eine Gleitkommazahl zwischen 0 und 1 angegeben.

- 18 -
Der Wert 0 definiert eine nicht-verfügbare Komponente, wohingegen der Wert 1 eine
vollständige Verfügbarkeit angibt.
3.3. Zustände von Services
Obwohl ein Service lediglich einen Rahmen für konkrete Komponenten darstellt, hat
er auch eigene explizite Zustände. Dies sind aggregierte Zustände seiner
Komponenten. Ein Service besitzt einen Error State und einen Availability Indicator.
Error State
Der Error State von einem Service ist Failed, sobald mindestens ein Error State
seiner Komponenten Failed ist; ansonsten ist er NoError.
Availability Indicator
Der Availability Indicator eines Services wird aus dem Mittelwert aus den Availability
Indicators seiner Komponenten gebildet.
3.4. Abhängigkeiten zu verschiedenen Komponentenzuständen
Bis
jetzt
wurde
nur
auf
Abhängigkeiten
zwischen
gleichartigen
Komponentenzuständen eingegangen. Im Folgenden werden Abhängigkeiten
zwischen verschiedenen Typen von Komponentenzuständen beschrieben:
Error State ­ Lifecycle State
Während dem Starten einer Komponente kann der Lifecycle State nur zum jeweils
nächst höheren Level ansteigen (also Deployed -> Created, Created -> Initialized
etc.) solange der Error State NoError bleibt. Ist der Error State einmal Failed, so wird
der Startprozess gestoppt.
Availability Indicator ­ Lifecycle State
Eine Komponente kann ihren Availability Indicator nur eigenmächtig setzen, wenn ihr
Lifecycle State Active ist. Ansonsten erzwingt der ComponentManager einen
Availability Indicator von 0.

- 19 -
4. Motivation
Das Zustandshandling im SDS Container ist komplex. Unterschiedliche
Ausprägungen einer Zustandsart sind voneinander abhängig. So aggregiert ein
Service Zustände seiner Komponenten. Überdies setzen Komponenten für ihre
Aktivierung voraus, dass assoziierte Komponenten zuvor aktiviert worden sind.
Analoges gilt beim Herunterfahren. Außerdem sind Instanzen unterschiedlicher
Zustandsarten voneinander abhängig. Beispielsweise ist ein Fortschreiten beim
Hochfahren einer Komponente nur im Error State NoError möglich.
Das Zustandshandling im SDS Container ist veränderlich. Derartige Verhaltensweise
ist nicht in Stein gemeißelt. Die Erfahrung bei Siemens zeigt, dass schon in
vergangenen Versionen in diesem Zusammenhang mehrere Änderungen vollzogen
worden sind. Auch der aktuelle Entwurf lässt unter Architekten Diskussionsbedarf zu.
Das bedeutet nicht, dass er schlecht sein muss. Dennoch ist und bleibt hier viel
Konzeptionelles schlichtweg Auslegungssache. Kritisch betrachtet werden kann z.B.
ob Anzahl und Interpretation der einzelnen Zustände im Lebenszyklus optimal sind.
Beim Availability Indicator kann man selbst über seine Existenz an sich streiten. Oder
auch über die Details, wie: Ist ein Gleitkommawert zwischen 0 und 1 nicht zu
allgemein? Sollte man hier keine feste Abstufung wählen?
Das Zustandshandling ist komplex und gegenüber Veränderungen anfällig. Diese
Symptome drängen zu einer flexiblen, gut durchdachten Lösung. Natürlich kann man
die
Abhängigkeiten
beim
Lifecycle
State
auch
direkt
in
der
Klasse
ComponentManager
ausprogrammieren. Das ist die Klasse, die eine einzelne
Komponente verwaltet und überwacht. Die Gefahr dabei ist, dass sie dadurch
überladen, undurchsichtig und letztendlich schwer wartbar wird; Keine guten
Voraussetzungen für etwas, das sich in Zukunft wahrscheinlich sowieso wieder bald
ändern wird. Oft helfen bei notwendigen Änderungen an einer komplexen, unflexiblen
Implementierung nur ein Löschen der entsprechenden Klassen und der radikale
Neuanfang.
Aus diesen Gründen wird zur Organisation der expliziten Zustände im SDS Container
ein flexibles Zustandsframework entworfen.

- 20 -
5. Konzeption
In diesem Kapitel wird das Zustandsframework vorgestellt, welches einen
zustandorientierten Programmieransatz unterstützt. Im Wesentlichen besteht das
Framework aus Klassen, deren Instanzen im Folgenden als sog. Zustandsobjekte
bezeichnet werden. Es werden jene Arten von Zustandsobjekten beschrieben, mit
denen das Lifecycle-Management im SDS Container umgesetzt werden kann.
Insofern orientiert sich das Framework an den Einsatz in einem Service-Container.
Dennoch sind zumindest die meisten elementaren Arten von Zustandsobjekten
(siehe 5.3.) recht universell verwendbar. In jedem Fall allgemeingültig ist das vorab
präsentierte Modell eines Zustandsobjekts mit dessen Transitionsalgorithmus.
5.1. Modell eines Zustandsobjekts
Zustandsobjekte sind Objekte im Sinne der OOP. Sie sind Behälter für Zustände.
Sie exponieren Zustände. Da es im Zusammenhang mit Zustandsobjekten nur so
von Zuständen wimmelt, wird der Eindeutigkeit halber der Zustand eines
Zustandsobjekts auch als exponierter Zustand bezeichnet. Die Zustände in einem
Zustandsobjekt sind von einem bestimmten Zustandstyp. Zustandsobjekte sind
parametrisiert durch einen Zustandstyp.
Ein Zustandstyp definiert eine Menge von zusammengehörigen Zuständen, die
durch Transitionen miteinander verkettet sind. Technisch gesehen werden
Zustandstypen üblicherweise durch Enumerationen, aber auch durch elementare
Typen (double, int
) abgebildet.
Zustandsobjekte besitzen zu jedem Zeitpunkt genau einen Zustand. Dieser wird
durch einen sog. Transitionsalgorithmus (bzw. Zustandsübergangsalgorithmus)
bestimmt. Der Transitionsalgorithmus ist durch die Art des Zustandsobjekts
festgelegt. Er besitzt meist verschiedene Eingabegrößen. Durch jede Änderung einer
Eingabegröße wird der Transitionsalgorithmus ausgeführt und ein oder mehrere
Zustandsübergänge finden statt, wenn sich der neu ermittelte Zustand vom
bisherigen Zustand unterscheidet.
Folgende Abbildung zeigt das Grundmodell eines Zustandsobjekts mit seinen Ein-
und Ausgabeobjekten:

- 21 -
Die Eingaben für den Transitionsalgorithmus werden vom Client und von sog.
Eingabe-Zustandsobjekten bestimmt. Der Client ist i.d.R. der Besitzer des
Zustandsobjekts und hat somit direkten Zugriff auf dessen öffentliche Methoden.
Generell kann er beliebige Parameter an den Transitionsalgorithmus übertragen und
damit
dessen
Ausführung
anstoßen.
Eingabe-Zustandsobjekte
sind
Zustandsobjekte, die den Transitionsalgorithmus zur Ausführung bringen, wenn sich
ihr eigener Zustand ändert.
Ist der Transitionsalgorithmus einmal gestartet, kann dieser während seiner
Ausführung einen Aktivitäten-Handler benutzen. Ein Aktivitäten-Handler ist primär
dazu da, die mit einer Transition verbundene Aktivität durchzuführen. Er wird
aufgerufen, wenn vorläufig ein neuer Zustand ermittelt wurde und hat daraufhin die
Möglichkeit, die entsprechende Transition zu blockieren, wenn die Abarbeitung der
Aktivität nicht erfolgreich war. In einem solchen Fall bleibt der bisherige Zustand
unberührt (deshalb vorläufig). Andernfalls wird der Zustand angenommen, so wie ihn
der Transitionsalgorithmus ermittelt hat.
Ausgaben des Transitionsalgorithmus sind Transitionen bzw. Zustandsübergänge,
was sich dadurch erkenntlich macht, dass er neue Zustände im Zustandsobjekt
installiert. Für die Benachrichtigung von Zustandsübergängen können sich beliebige
Objekte
registrieren.
Diese
werden
Transitions-Listener
genannt.
Transitions-
algorithmus
Aktivitäten-
Handler
Zustand
Eingabe-
Zustands-
objekte
Transitions-
Listener
[Zustandstyp]
Client

- 22 -
Benachrichtigungen über Transitionen werden grundsätzlich in derselben
Reihenfolge ausgeliefert, in der sie ausgelöst wurden (also: First come, first served).
Für die Verkettung von Zustandsobjekten zu ihren Eingabe-Zustandsobjekten wird
derselbe Mechanismus verwendet, damit sie von deren Transitionen benachrichtigt
werden. Ein Zustandsobjekt registriert sich bei dessen Eingabe-Zustandsobjekte für
Zustandsübergänge. Demnach ist es selbst Transitions-Listener seiner Eingabe-
Zustandsobjekte.
Die Existenz von Eingabegrößen, durch Client oder Eingabe-Zustandsobjekt zur
Verfügung gestellt, sowie von Transitions-Listenern als auch von Aktivitäten-
Handlern ist grundsätzlich optional. Allerdings sind mindestens eine Eingabegröße
und ein Transitions-Listener erforderlich, andernfalls ist die Notwendigkeit eines
entsprechenden Zustandsobjekts ad absurdum geführt.
5.2. Transitionsalgorithmus
Während schon im letzten Abschnitt der Transitionsalgorithmus grob vorgestellt
wurde und dabei insbesondere seine externen Schnittstellen beschrieben sind, wird
in diesem Abschnitt vor allem die innere Struktur näher beleuchtet.
Die nächste Abbildung zeigt das Modell des Transitionsalgorithmus im Überblick:
Exponierter
Zustand
Zielfunktion
Aktivitäten-
Handler
Client
Transfer-
algorithmus
Eingabe-
Zustands-
objekte
Zielzustand
Auftrag für
eine einzelne
Transition
Positive oder
Negative
Rückmeldung

- 23 -
Der
Transitionsalgorithmus
besteht
aus
einer
Zielfunktion
und
einem
Transferalgorithmus. Die Zielfunktion erhält Eingaben von außen, also entweder
vom Client oder von Eingabe-Zustandsobjekten. Er ermittelt einen Zielzustand, den
er an den Transferalgorithmus übergibt. Der Transferalgorithmus strebt die
Überführung des bisherigen exponierten Zustands zum Zielzustand an. Wie dies
prinzipiell vonstatten geht, bestimmt der sog. Transitionsmodus.
Bislang sind zwei verschiedene Transitionsmodi definiert, wenngleich auch noch
weitere denkbar wären:
1. Direkt: Dieser Modus ist wohl der nächstliegende. Es wird versucht einen
unmittelbaren Zustandsübergang vom bisherigen Zustand zum Zielzustand
durchzuführen.
2. Sequentiell: Dieser Modus setzt einen sequentiellen Zustandstyp voraus. Das
bedeutet, die möglichen Zustände müssen in einer Reihe definiert sein. Die
Zustände haben grundsätzlich einen eindeutigen Vorgängerzustand und einen
eindeutigen Nachfolgezustand. Ausnahmen sind der kleinste Zustand, der
lediglich einen eindeutigen Nachfolgezustand kennt und der größte Zustand
mit nur einem eindeutigen Vorgängerzustand. Die Zustände sind demnach in
einer nicht-zyklischen doppelt verketteten Liste angeordnet.
Ist ein sequentieller Zustandstyp gegeben, so wird beim sequentiellen
Transitionsmodus der bisherige Zustand sukzessive in den Zielzustand
überführt; entweder aufsteigend in der definierten Reihenfolge der Zustände
oder absteigend. Je nachdem, ob der Zielzustand größer oder kleiner als der
bisher exponierte Zustand ist.
Hierbei werden ggf. mehrere Transitionen durch nur einmaliges Anstoßen des
Transferalgorithmus durchgeführt. Wichtig ist, dass bei jeder einzelnen
Transition auch die Transitions-Listener informiert werden müssen.
Wenn der Transferalgorithmus für Transitionen mit einem Aktivitäten-Handler
kommuniziert, spricht man von sog. geführten (managed) Transitionen. Bei jeder
einzelnen vorgesehenen Transition erteilt der Transferalgorithmus dem Aktivitäten-
Handler den Auftrag, die mit einer Transition verbundene Aktivität durchzuführen.
Wenn die Aktivität erfolgreich war, liefert der Handler eine positive Rückmeldung,

Details

Seiten
Erscheinungsform
Originalausgabe
Jahr
2007
ISBN (eBook)
9783836606868
DOI
10.3239/9783836606868
Dateigröße
1015 KB
Sprache
Deutsch
Institution / Hochschule
Fachhochschule Regensburg – Informatik / Mathematik, Studiengang Wirtschaftsinformatik
Erscheinungsdatum
2007 (Dezember)
Note
1,0
Schlagworte
zustandsorientierung programmierung container framework service-container
Zurück

Titel: Framework für Zustandsorientierte Programmierung
book preview page numper 1
book preview page numper 2
book preview page numper 3
book preview page numper 4
book preview page numper 5
book preview page numper 6
book preview page numper 7
book preview page numper 8
book preview page numper 9
book preview page numper 10
book preview page numper 11
book preview page numper 12
book preview page numper 13
book preview page numper 14
book preview page numper 15
book preview page numper 16
book preview page numper 17
book preview page numper 18
book preview page numper 19
book preview page numper 20
book preview page numper 21
book preview page numper 22
book preview page numper 23
107 Seiten
Cookie-Einstellungen