Kapitel IV
Analyse
Architektur
Implementierung
Vorgehensweise bei der Entwicklung neuer Uhren
Analyse
Die Idee besteht im zweiten Ansatz darin, den Bezug zur realen Welt
herzustellen. Dazu werden folgende Überlegungen gemacht:
- Eine Uhr besteht aus den Elementen Gehäuse, Zifferblatt und drei
Zeigern.
- Das Gehäuse, das Zifferblatt sowie die Zeiger bestehen wiederum
aus anderen Elementen. Diese werden jedoch nicht weiter betrachtet.
- Ein Wecker besteht aus Bedienelementen zum Einstellen der Weckzeit,
zum Abschalten des Wecksignal und zum Aktivieren bzw. Deaktivieren des
Weckers. Diese Bedienelemente werden aufgrund der Komplexität ebenfalls
nicht weiter betrachtet.
- Wecker und Uhr müssen miteinander kommunizieren, um die Funktionalität
des Weckers gewährleisten zu können. Hierbei gibt es folgende
Möglichkeiten:
- Wecker hat eine Referenz auf eine Uhr
Wecker kann somit den Zustand der Uhr erfragen und daher seine Funktionalität
gewährleisten. Doch wann bzw. wie oft soll das Erfragen des Status
erfolgen. Nach genaueren Betrachtungen wird man wohl zu dem Schluß
kommen, daß diese Beziehung nicht sinnvoll ist und daher verworfen wird.
- Uhr hat eine Referenz auf einen Wecker
Die Uhr ruft in bestimmten Zeitintervallen eine Methode von Wecker auf,
wobei die Uhrzeit als Parameter übergeben wird. Der Wecker kann aufgrund
dessen seine Funktionaltität garantieren. Jedoch müssen Maßnahmen
getroffen werden, die garantieren, daß die Uhr nur die Methoden aufruft,
die tatsächlich auch vorgesehen sind.
- Uhr hat eine Referenz auf einen Wecker und Wecker hat eine Referenz
auf eine Uhr
Beim objektorientierten Design sollte stets darauf geachtet werden, daß
die Abhängigkeiten zwischen den einzelnen Klassen möglichst gering
ist, so daß die Fehlerquellen und Fehlerursachen minimal werden.
Da b) weit weniger Abhängigkeiten als diese Möglichkeit besitzt,
wird c) nicht weiter beachtet.
Architektur
- Uhr
Die Zeiger und das Zifferblatt werden jeweils in eigenständigen Klassen
(UhrZeiger und Zifferblatt) implementiert. Das Gehäuse
wird nicht weiter betrachtet.
Die Uhr wird ebenfalls in einer eigenen Klasse entwickelt. Bei der
Kreation einer Uhr werden automatisch das zugehörige Zifferblatt sowie
die dazugehörigen Zeigen erzeugt. Die Klasse Uhr besitzt somit ein
Objekt der Klasse Zifferblatt sowie drei Objekte der Klasse UhrZeiger.
Da die Uhr eine Referenz auf einen "Wecker" hat, stellt sich
die Frage, wie die Schnittstelle von "Wecker" zu definieren ist,
damit die Uhr nur gewisse Methoden aufrufen kann. Die Antwort auf diese
Frage ist einfach. (Dieses Problem wurde in gleicher Art und Weise bereits
von der Klasse Thread gelöst.) Hierbei geht man folgendermaßen
vor:
- Definition eines Interfaces Actionable. Dieses Interface sieht
folgendermaßen aus:
interface Actionable {
public void action( Uhrzeit uhrzeit );
}
Uhrzeit ist eine Klasse bestehend aus den public-Attributen hours,
minutes und seconds vom Typ int.
Jede Klasse, die geweckt werden will, muß das Interface Actionable
implementieren.
Die Uhr erhält eine Referenz auf ein Objekt, das Actionable
implementiert hat (In unserem Fall also die Klasse Wecker). Dieses Objekt
ist der Kommunikationspartner der Uhr.
Auf diese Weise wird garantiert, daß die Uhr nur die Methoden
aufruft, die auch erlaubt sind. Ferner kann somit die Uhr in den verschiedensten
Klassen, die vielleicht erst in Zukunft entwickelt werden, eingesetzt werden.
Das heißt die Verwendung des Interfaces Actionable garantiert
die Wiederverwendung der Klasse Uhr (sowie Polymorphismus).
Die Uhr sollte zwei Konstruktoren besitzen:
- Konstuktor ohne Actionable
Wird eine Uhr auf diese Weise erzeugt, so wird die Uhr standalone genutzt.
- Konstruktor mit Actionable
Wird eine Uhr auf diese Weise erzeugt, so sendet die Uhr in bestimmten
Zeitabschnitten dem übergebenen Objekt eine Nachricht über die
Methode action. Das aufgerufene Objekt kann anschließend seine
Verarbeitung wahrnehmen.
Wecker
Diese Klasse implementiert den Wecker. Bei der Kreation werden die Bedienelemente
erzeugt. Als Bedienelemente werden folgende GUI-Komponenten herangezogen:
zwei Scrollbars zum Einstellen der Weckzeit, eine Checkbox zum Aktivieren
bzw. Deaktivieren des Weckers sowie einem Button zum Abstellen des Wecksignals.
Neben jedem Scrollbar wird der Wert des Scrollbars ( 0-59 für Minuten,
0-23 für Stunden) angezeigt. Der Wert wird in einem Label abgelegt.
Scrollbar und Label werden zusammen als eine neue GUI-Komponente Slider
entwickelt. Slider wurde so entworfen, als sei diese Klasse eine
Standard-GUI-Komponente, so daß die Handhabung einfach ist und die
Wiederverwendbung des Bausteins garantiert wird.
( Die Funktionalität wird durch obige Beschreibung der Kommunikation
zwischen Uhr und Wecker gewährleistet. )
Implementierung
Beispiel für eine Implementierung der Klassen UhrZeiger,
Zifferblatt, Uhr, Slider und Wecker.
Auf einer genaue Beschreibung der Methoden der einzelnen Klassen wird
verzichtet, da die Implementierung keine besondere Rolle spielt. Schließlich
ist das Konzept und die Architektur das Wesentliche einer Applikation.
Fazit
Beim genaueren Hinsehen wird man bemerken, daß der zweite Ansatz
viel mehr Klassen besitzt als der erste. Durch die feinere Struktur bzw.
durch viele kleine Objekte/Klassen kann die Wiederverwendbarkeit enorm
gesteigert werden. Die einzelnen kleinen Klassen haben jeweils nur eine
geringere Funktionalität. Erst durch die Zusammenfassung dieser kleinen
Klassen zu neueren und durch Interaktion der Objekte untereinander, entstehen
Klassen mit meist sehr komplexen Verhalten.
Nachteile, die sich durch die Zerlegung ergeben, sind:
- mehr Aufwand für die Analyse erforderlich
- mehr Aufwand für Erstellung der Architektur erforderlich
- mehr Aufwand für die Erstellung einer "schmalen" Schnittstelle
erforderlich
Vorgehensweise bei der Entwicklung neuer Uhren
- Erstellung von neuen Elementen, die die oben genannten Klassen (UhrZeiger
oder Zifferblatt) als Oberklasse haben.
- Redefinition von relevanten Methoden.
- Definition einer neuen Uhr-Klasse, die von der Klasse Uhr abgeleitet
ist.
- Relevante Methoden von Uhr überschreiben, so daß
nicht die neuen Elemente erzeugt und initialisiert werden.
Beispiel:
Es wird eine Uhr benötigt, die sich lediglich von der Klasse Uhr
darin unterscheidet, daß die neue Uhr andere Zeiger verwendet. Dazu
geht man wie folgt vor:
- Definition einer neuen Uhrzeiger-Klasse mit dem Namen ModernZeiger
und Redefinition von show und hide
- Definition einer neuen Uhr-Klasse mit dem Namen ModernUhr
und Redefinition von createZeiger
Beispiel
für ein Applet mit Uhr und ModernUhr.
Hier das Applet:
|
Allgemeines über Java
|
|
|
Java-Applets und ihre Funktionsweise
|
|
|
|
|
Interessante Links
|
|
|
Einfürung in Java anhand konkreter Bespiele
|
Copyright © Quoc-Thanh
Lam & Marco Lauer