Objektorientierte Bausteine und Bibliotheken, Teil 1

Werbung
Programmbausteine & Komponenten
5.4 Objektorientierte Bausteine
und Bibliotheken
Wir verwenden die Begriffe „Programmbaustein“
und „Programmkomponente“ hier synonym.
Idee:
Dieser Abschnitt führt in den Komponenten-/
Bausteinbegriff und in die Java-Bibliothek ein.
Ziel ist die Vertiefung der in 5.3 erläuterten
Konzepte und deren Anwendung.
Konstruiere Softwaresysteme aus vorgefertigten
Bausteinen durch
• Anpassen der Bausteine:
Überblick:
- Instanzieren von Parametern
- Spezialisierung
• Bausteine, Schnittstellen und Bibliotheken
• Verbinden der Bausteine/Komposition:
• Klassen zur Ausnahmebehandlung
- Verbindungsmechanismen der Komponenten
• Ströme zur Ein- und Ausgabe
- zusätzlicher Programmcode (engl. glue code)
5.4.1 Bausteine, Schnittstellen und
Bibliotheken
Wichtige Fragestellungen:
• Klärung und Diskussion der Begriffe
- Sind die Bausteine direkt einsetzbar oder müssen
sie noch vervollständigt werden?
- Wie anpassbar, wie allgemein sind die Bausteine?
- Programmbaustein, -komponente
- Sind die Bausteine unabhängig voneinander,
hierarchisch strukturiert, wechselseitig abhängig?
- API, Programmierschnittstelle
- Bibliothek
- Wie werden sie zusammengesetzt?
• Überblick über die Java-Bibliothek
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
- Wie kann man sie auffinden?
672
Vereinfachend gehen wir davon aus, dass ein
Baustein durch eine oder mehrere Typdeklarationen
realisiert ist. Die Schnittstelle eines Bausteins
entspricht der öffentlichen Schnittstelle dieser Typen.
05.02.2007
public final
class Boolean implements java.io.Serializable {
public static final Boolean TRUE =
new Boolean(true);
public static final Boolean FALSE =
new Boolean(false);
public static final Class TYPE = ...;
- unabhängige Bausteine
- eigenständige Bausteine
- kooperierende Bausteine
public Boolean(boolean value) {
this.value = value;
}
public Boolean(String s) {
this( toBoolean(s) );
}
public boolean booleanValue(){ return value; }
public static Boolean valueOf(String s){...}
public String toString() { ... }
public int hashCode() { ... }
public boolean equals(Object obj) {
if (obj instanceof Boolean) {
return value ==
((Boolean)obj).booleanValue();
}
return false;
}
public static boolean getBoolean(String n){..}
Wir erläutern diese Aufteilung jeweils durch
Begriffsklärung und Beispiele in Java.
Begriffsklärung: (unabhängige Bausteine)
Wir nennen Bausteine oder Programmkomponenten
unabhängig, wenn sie ohne Kenntnis und Existenz
anderer Bausteine bzw. Komponenten angewandt
werden können.
In der Schnittstelle unabhängiger Bausteine kommen
im Wesentlichen nur vordefinierte und Standardtypen
vor.
Typische Beispiele sind einfache Behälterbausteine
(z.B. SLinkedList), die Klasse String oder die
Wrapper-Klassen, aber auch vollständige
Anwendungsprogramme.
© A. Poetzsch-Heffter, Universität Kaiserslautern
673
Beispiel: (unabhängiger „Baustein“)
Wir betrachten drei Arten von Bausteinen:
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
}
674
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
675
Beispiel: (eigenstängiger Baustein)
Unabhängigkeit erleichtert das Verständnis
von Bausteinen. Trotzdem sind unabhängige
Bausteine in Programmbibliotheken eher selten.
Listen mit Iteratoren bilden einen Baustein. Als
Beispiel betrachten wir die Typen LinkedList, Iterator
und ListIterator aus dem Paket java.util.
Häufig sind unterschiedliche, aber ähnliche
Bausteine Teil einer Klassen- bzw. Typhierarchie.
Dadurch sind speziellere Bausteine oft von
allgemeineren abhängig.
public interface Iterator {
boolean hasNext();
Object next();
void remove();
}
Begriffsklärung: (eigenständige Bausteine)
Wir nennen Bausteine oder Programmkomponenten
eigenständig, wenn die Kenntnis und Existenz ihrer
Supertypen für ihr Verständnis und ihre Anwendung
ausreicht und sie eingesetzt werden können, ohne
mit anderen Bausteinen kooperieren zu müssen.
In der Schnittstelle eigenständiger Bausteine kommen
im Wesentlichen nur vordefinierte Typen, Standardtypen und Supertypen der Klassen vor, die den Baustein implementieren.
Typische Beispiele sind komplexere Behälterbausteine
und Stromklassen.
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
676
public class LinkedList
extends AbstractSequentialList
implements List, Cloneable, Serializable
{
public LinkedList()
public LinkedList(Collection c)
public Object getFirst()
public Object getLast()
public Object removeFirst()
public Object removeLast()
public void addFirst(Object o)
public void addLast(Object o)
public boolean contains(Object o)
public int size()
public boolean add(Object o)
public boolean remove(Object o)
public boolean addAll(Collection c)
public boolean addAll(int ix, Collection c)
public void clear()
public Object get(int index)
public Object set(int ix, Object elem)
public void add(int index, Object elem)
public Object remove(int index)
public int indexOf(Object o)
public int lastIndexOf(Object o)
// ... weiter nächste Seite
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
678
public interface ListIterator
extends Iterator {
boolean hasNext();
Object next();
boolean hasPrevious();
Object previous();
int nextIndex();
int previousIndex();
void remove();
void set(Object o);
void add(Object o);
}
05.02.2007
// ...
public
public
public
public
public
public
public
public
public
... //
© A. Poetzsch-Heffter, Universität Kaiserslautern
677
ListIterator listIterator()
ListIterator listIterator(int ix)
Iterator iterator()
List subList(int from, int to)
boolean equals(Object o)
int hashCode()
Object clone()
Object[] toArray()
Object[] toArray(Object a[])
Methoden aus Object
}
Bemerkung:
In Abschnitt 5.4.3 werden wir weitere eigenständige
Bausteine kennen lernen.
Im Allg. agieren Bausteine nicht eigenständig,
sondern müssen mit anderen und andersartigen
Bausteinen kooperieren, um ihre Funktionalität
zu erbringen.
Bausteine können eng oder nur lose kooperieren.
Enge Kooperation findet man typischerweise in
Programmgerüsten (engl. program frameworks).
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
679
Bemerkung:
Die Kooperation zwischen Bausteinen kann
man syntaktisch an den (rekursiven) Abhängigkeiten
der Typdeklarationen erkennen.
• Die Grenzen eines Bausteins werden vom
Bausteinentwickler festgelegt und lassen sich
im Allg. nicht aus dem Programmtext erschließen.
• Die Unterscheidung zwischen den Bausteinarten
ist nicht scharf.
Beispiel: (Abhängigkeiten bei Kooperation)
Folgende Fragmente stammen aus dem AWT
(Pakete java.awt, etc.), einem Java-Framework
zur Implementierung graphischer Bedienoberflächen.
Begriffsklärung: (Programmierschnittstelle)
class Component ... {
...
void addComponentListener(ComponentListener c)
...
}
interface ComponentListener ... {
...
void componentResized( ComponentEvent e );
...
}
Die Programmierschnittstelle eines Bausteins (einer
Komponente) besteht aus den öffentlichen Typen
und Methoden, mit denen der Baustein aus
Programmen heraus gesteuert werden kann.
In gleicher Weise spricht man von der Programmierschnittstelle einer Anwendung oder eines Systems
(engl. application programming interface, API).
Beispiele: (Programmierschnittstellen)
Es gibt Programmierschnittstellen für den:
• Zugriff aufs Dateisystem
class ComponentEvent ... {
...
Component getComponent() ...
...
}
• Zugriff auf andere Teile des Betriebssystems
• Zugriff aufs Netzwerk
• Zugriff auf eine Anwendung, etwa ein Spiel
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
680
Bemerkung:
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
Wichtige Pakete der Java-Bibliothek
Nicht alles, was sich API nennt, ist in obigem Sinne
eine Programmierschnittstelle.
Begriffsklärung: (Programmbibliothek)
Eine Programmbibliothek oder einfach Bibliothek
ist eine strukturierte Ansammlung von Programmteilen,
die für die Wiederverwendung entwickelt und
organisiert sind.
Die Programmteile können unterschiedlicher Art
sein (z.B. standardisierte Bausteine der Sprache,
eigenständige Bausteine, Programmierschnittstellen,
Programmgerüste).
applet
event
awt
font
beans
image
io
ref
lang
java
math
registry
rmi
Beispiele: (Programmbibliotheken)
server
• zu Programmiersprachen gehörende Bibliotheken
(z.B. Java-Bibliothek)
security
• Bibliotheken für Datenstrukturen: STL, Leda, ...
sql
• Bibliotheken für graphische Bedienoberflächen,
zu allgemeinen Anwendungsbaukästen
text
• Bibliotheken für Graphik, CAD, virtuelle Welten, ...
util
zip
javax.*
• Anwendungsspezifische Bibliotheken
org. *
© A. Poetzsch-Heffter, Universität Kaiserslautern
reflection
net
nio
05.02.2007
681
682
05.02.2007
jar
© A. Poetzsch-Heffter, Universität Kaiserslautern
683
Bemerkung:
Es gibt drei Arten von Ausnahmesituationen:
Die obige Darstellung der Java-Bibliothek ist
unvollständig. Beispielsweise enthält das
Paket javax.swing ein leistungsfähigeres
Programmgerüst zur Realisierung graphischer
Bedienoberflächen (GUI Framework).
1. Nicht korrigierbare Ausnahmesituationen (Error):
Drei typische Beispiele:
- kein Speicherplatz mehr verfügbar zum Erzeugen
von Objekten (OutOfMemoryError)
5.4.2 Klassen zur Ausnahmebehandlung
- zuviele unbeendete Methodenaufrufe
(StackOverflowError)
Realisierung der Ausnahmebehandlung in Java
demonstriert zwei Aspekte:
- Inkonsistenzen zwischen übersetzten Klassen
(z.B. AbstractMethodError)
- erweiterbare Hierarchie einfacher Bausteine
- Zusammenspiel von Sprache und Standardbibliothek
2. Programmierfehler (RuntimeException):
Typische Beispiele:
Darüber hinaus ist das Verständnis der Ausnahmebehandlung von allgemeinem Interesse für die
Softwareentwicklung.
- Dereferenzieren von null (NullPointerException):
Object ov = null;
ov.equals( new Object() );
Klassifikation von Ausnahmesituationen
- Feldzugriff mit unzulässigem Index
(IndexOutOfBoundsException):
Die möglichen Ausnahmesituationen werden in
Java durch eine Typhierarchie klassifiziert.
int[] iav = new int[37];
Alle Ausnahmeklassen sind Subklassen von
java.lang.Throwable
© A. Poetzsch-Heffter, Universität Kaiserslautern
05.02.2007
int n = iav[333];
684
3. Nicht vermeidbare, aber behandelbare Situationen:
Beispiele sind der Zugriff auf eine Ressource,
etwa das Netz oder eine Datei, die augenblicklich
anderweitig genutzt wird.
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
685
Insgesamt ergibt sich folgende Klassifikation bzw.
Typhierarchie:
Object
Abhilfe:
Throwable
- zeitverzögert nochmaligen Zugriff
- Anwendung einer vergleichbaren Ressource.
Error
Exception
In diese Kategorie fallen auch die meisten anwendungsspezifischen Ausnahmen.
IOException
AbstractMethodError
ClassNotFoundException
OutOfMemoryError
Beispiel: (anwendungsspez. Ausnahmekl.)
KeinKaffeeException
StackOverflowError
public class KeinKaffeeException
extends Exception {
private float restMenge;
RuntimeException
KeinKaffeeException( float kaffeeMenge ){
restMenge = kaffeeMenge;
NullPointerException
}
IndexOutOfBoundsException
public float getRestMenge() {
return restMenge;
IllegalArgumentException
}
}
NumberFormatException
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
686
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
687
Zusammenspiel von Sprache und Bibliothek
3. Aspekt:
Behandlung von Ausnahmen:
Die Ausnahmebehandlung in Java hat vier Aspekte:
- im umfassenden try-Block;
- Welche Ausnahmen gibt es?
- die aktuelle Methode terminiert abrupt und reicht die
Ausnahme an die Aufrufstelle weiter.
- Wodurch werden Ausnahmen ausgelöst?
- Wie werden Ausnahmen ggf. über Methodengrenzen hinweg weitergereicht?
- Wie kann man Ausnahmen abfangen und behandeln?
Der Java-Übersetzer prüft, welche Ausnahmen eine
Methode möglicherweise auslöst, ohne sie abzufangen.
Alle nicht-abgefangenen Ausnahmen, die weder
Subklassen von Error noch von RunTimeException
sind, müssen in der Signatur der Methode deklariert
werden (siehe Beispiel).
1. Aspekt:
In Java werden Ausnahmen als Subklassen von
Throwable realisiert. D.h.
- vordefinierte Ausnahmen in der Standardbibliothek
4. Aspekt:
- benutzerdefinierte Ausnahmen als Subklassen
Mittels der try-catch-Anweisung kann man Ausnahmen
(und Fehler) abfangen:
2. Aspekt:
try {
Fehler und Laufzeitausnahmen werden durch das
Laufzeitsystem von Java (Java Virtual Machine)
ausgelöst.
} catch( <Subtyp von Throwable> eb ) {
<Anweisungsblock1>
<Anweisungsblock2>
} ...
Andere Ausnahmen durch Systemschnittstellen oder
Anwenderprogramme mittels der throw-Anweisung.
Tritt im Anweisungsblock1 eine Ausnahme vom Typ E
auf und ist E ein Subtyp des Typs, der in der catchKlausel genannt ist, dann wird die Ausnahme
abgefangen und der Anweisungsblock2 ausgeführt.
Der Ausdruck in der throw-Anweisung muss ein
Subtyp von Throwable sein.
© A. Poetzsch-Heffter, Universität Kaiserslautern
05.02.2007
688
Andernfalls wird die Ausnahme weitergereicht.
Beispiel: ( Ausnahmebehandlung)
public class KaffeeMaschine {
private KaffeeSpeicher speicher;
...
void fuellenFilter( float benoetigteMenge )
throws KeinKaffeeException {
float restMenge;
restMenge = speicher.messenFuellung();
if( restMenge < benoetigteMenge ) {
throw new KeinKaffeeException(restMenge);
}
...
}
}
Bemerkung:
• Häufig kann die Behandlung der Ausnahme erst
von einem weiter außen liegenden Aufrufer erledigt
werden.
• Eine überschreibende Methode darf nur die Ausnahmen auslösen, die auch die überschriebene
Methode auslösen darf.
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
690
05.02.2007
© A. Poetzsch-Heffter, Universität Kaiserslautern
689
Herunterladen