6.1 Beispiel
-
Für die nachfolgenden Beispielprogramme soll angenommen werden, dass ein Objekt ("Datensatz") aus 3 Attributen ("Datenfeldern") besteht.
- Ein solches Objekt beschreibt einen Schüler mit den Attributen
- "Name" (Zeichenkette mit beliebig viele Zeichen),
- "Notendurchschnitt" (rationale Zahl vom Typ
float
) und- "Klasse" (Zeichenkette mit einer fixen Anzahl von Zeichen - in diesem Beispiel immer genau 7 Zeichen).
- "Notendurchschnitt" (rationale Zahl vom Typ
Über die Standardeingabe (Tastatur) sollen zunächst die Attribute von mehreren Schülerobjekten eingelesen und danach in einer Datei gespeichert werden. Dazu werden 2 Klassen definiert: die Klasse DAOerfassenSchueler
zum Erfassen der Daten und die Klasse DAOschreibenSchueler
zum Schreiben (Speichern) der Daten. Ein Schüler wird repräsentiert als Instanz einer Klasse Schueler
.
Eine zweite Anwendung soll die Datei lesen und die Daten der Datei auf der Standardausgabe (Bildschirm) anzeigen. Zu diesem Zweck gibt es die Klasse DAOlesenSchueler
, die das Lesen der gespeicherten Daten ermöglicht. Eine weitere Klasse - DAOausgebenSchueler
- ist zuständig für das Aufbereiten und Ausgeben der Daten.
Die 4 Klassen zum Erfassen, Schreiben, Lesen und Ausgeben der Daten sind sog. DAO-Klassen ("Data Access Object"), die Klasse Schueler
ist eine sog. Model-Klasse ("model" engl. für "Daten").
- Bem.:
- Es wäre durchaus sinnvoll, die 3 erstgenannten Klassen zu 1 einzigen zusammenzufassen, denn die Datenerfassung mit Speichern und späterem Lesen definiert die Schnittstelle zu dem erwähnten Objekt ("Datei"). Auf diese Weise sind die Beispielprogramme und die darin geübten Techniken jedoch leichter zu verstehen.
- Die 4. Klasse (
DAOausgebenSchueler
) jedoch ist nicht abhängig von der Datei, sondern nur von den Wünschen der Benutzer, die die Daten anschauen möchten (beispielsweise könnte man die Daten in einer Tabelle darstellen). - Die 4. Klasse (
- Zu den Klassen:
- Model-Klasse Schueler
- DAO-Klassen
- DAOerfassenSchueler
- DAOschreibenSchueler
- DAOlesenSchueler
- DAOausgebenSchueler
- DAO-Klassen
- Zu den Anwendungsprogrammen:
- Programmklassen
- Anwendungsklasse ErfassenSchreiben
- Anwendungsklasse LesenAusgeben
- Anwendungsklasse ErfassenSchreiben
- Zum UML-Klassendiagramm:
- Allgemeines Klassendiagramm für die DAO-Klassen
6.1.1 Model-Klasse Schueler
für Daten
Klasse Schueler |
---|
/* * Schueler.java */ package at.beringer.oopBuch.modelKlassen; /** Datenklasse ('Model'-Klasse) für eine Datenstruktur mit 3 Datenfeldern. <p> Diese Klasse dient als 'Model'-Klasse für die Demo-Programme zur Verarbeitung von Dateien und Datenbanken. Objekte dieser Klasse (genauer: deren Attribute) werden als Datensätze in einer Datei bzw. als Zeilen in einer Datenbank-Tabelle gespeichert. </p> <p> Jede Instanz dieser Klasse repräsentiert einen Schüler mit <ul> <li>Name</li> <li>Notendurchschnitt</li> <li>Klassenbezeichnung</li> </ul> </p> <p> Das 1. Datenfeld (Name) beinhaltet eine Zeichenkette, die beliebig lang sein kann (d.h. die Zeichenkette hat eine variable Länge). <br /> Das 2. Datenfeld (Notendurchschnitt) beinhaltet einen float-Wert. <br /> Das 3. Datenfeld (Klassenbezeichnung) beinhaltet eine Zeichenkette mit einer fixen Anzahl von Zeichen - in diesem Fall die Klassenbezeichnung mit immer genau 7 Zeichen (d.h. die Zeichenkette hat eine fixe Länge). </p> <p> Der Einfachheit halber ist die 'toString'-Methode nicht internationalisiert. </p> <hr /> @since August 2000 @version Juli 2002 (Zeichenkette mit variabler Länge) @version <br />Juni 2006 (Methode 'toString' überschreiben) @version <br />Juli 2014 (Verschieben in Paket 'modelKlassen') @see at.beringer.oopBuch.daoKlassen.DAOerfassenSchueler @see at.beringer.oopBuch.daoKlassen.DAOschreibenSchueler @see at.beringer.oopBuch.daoKlassen.DAOschreibenDBSchueler @see at.beringer.oopBuch.daoKlassen.DAOlesenSchueler @see at.beringer.oopBuch.daoKlassen.DAOlesenDBSchueler @see at.beringer.oopBuch.daoKlassen.DAOausgebenSchueler @see at.beringer.oopBuch.daoKlassen.DAOausgebenSchuelerString @author Beringer Alfred */ public class Schueler { // ------------------------------------------------------------------------- // Klassenkonstante // ------------------------------------------------------------------------- /** Zeichenkette mit einer fixen Anzahl von Leerzeichen. Sie dient zum Auffüllen einer zu kurzen Zeichenkette mit Leerzeichen. <p> Die Initialisierung erfolgt im Klassenkonstruktor. </p> */ public static final String KLASSELEER; // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private String name; // Zeichenkette mit variabler Länge private float notenschnitt; // float-Zahl private String klasse; // Zeichenkette mit fixer Länge // ------------------------------------------------------------------------- // Klassenkonstruktor // ------------------------------------------------------------------------- /** Klassenkonstruktor (Klassen-Initialisierungsblock). <p> Die Werte für nicht initialisierte Klassenkonstante könnten von externen Datenquellen geholt werden (z.B. von einer Datei, einer Datenbank oder von einer Properties-Datei). </p> <p> Der Einfachheit halber werden die Werte fix vorgegeben - in diesem Fall eine Zeichenkette mit genau 7 Leerzeichen. </p> */ static { KLASSELEER = " "; // Zeichenkette mit genau 7 Leerzeichen } // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert das erste Datenfeld (Name) - eine Zeichenkette mit variabler Länge. @return Name (1. Datenfeld) */ public String getName() { return name; } // ---------- /** Ändert das erste Datenfeld (Name). @param name neuer Name (Zeichenkette mit variabler Länge) */ public void setName(String name) { this.name = name; } // ------------------------------------------------------------------------- /** Liefert das zweite Datenfeld (Notendurchschnitt) - ein float-Feld. @return Notendurchschnitt (2. Datenfeld) */ public float getNotenschnitt() { return notenschnitt; } // ---------- /** Ändert das zweite Datenfeld (Notendurchschnitt). @param notenschnitt neuer Notendurchschnitt (float-Wert) */ public void setNotenschnitt(float notenschnitt) { this.notenschnitt = notenschnitt; } // ------------------------------------------------------------------------- /** Liefert das dritte Datenfeld (Klassenbezeichnung) - eine Zeichenkette mit fixer Länge. @return Klassenbezeichnung (3. Datenfeld) */ public String getKlasse() { return klasse; } // ---------- /** Ändert das dritte Datenfeld (Klassenbezeichnung) und kontrolliert auch gleichzeitig die Länge dieses Feldes. <p> Eine zu kurze Zeichenkette wird mit Leerzeichen aufgefüllt, eine zu lange wird einfach abgeschnitten. </p> @param klasse neue Klassenbezeichnung (Zeichenkette mit fixer Länge) */ public void setKlasse(String klasse) { // mit Leerzeichen erweitern: this.klasse = klasse + KLASSELEER; // kürzen auf fixe Länge: this.klasse = this.klasse.substring(0,KLASSELEER.length()); } // ------------------------------------------------------------------------- // Methode 'toString' // ------------------------------------------------------------------------- /** Überschreiben der Methode 'String Object.toString()'. <p> Liefert eine beschreibende Text-Darstellung einer Instanz der Klasse: <pre> Schueler[ Name = ... (Länge = ...), Notendurchschnitt = ..., Klassenbezeichnung = *...* ] </pre> </p> <p> Die Texte sind der Einfachheit halber Literale. </p> @see java.lang.Object#toString() @return Zeichenkette, die eine Instanz beschreibt */ @Override public String toString() { StringBuilder text = new StringBuilder(this.getClass().getSimpleName()); text.append("[ Name = " ).append(name ).append( " (Länge = " ).append(name.length()).append( "), Notendurchschnitt = " ).append(notenschnitt ).append( ", Klassenbezeichnung = *").append(klasse ).append("* ]"); return new String(text); } } |
6.1.2 DAO-Klassen
6.1.2.1 Klasse DAOerfassenSchueler
für Datenerfassung (Standardeingabe)
Klasse DAOerfassenSchueler |
---|
/* * DAOerfassenSchueler.java */ package at.beringer.oopBuch.daoKlassen; import java.io.*; import at.beringer.oopBuch.modelKlassen.Schueler; /** DAO-Klasse für das Erfassen von Schülerdaten von der Standardeingabe (= Tastatur). <p> Die Schülerdaten werden in 'Schueler'-Objekten aufbereitet. </p> <p> Methoden 'oeffnen' und 'schliessen' sind nicht notwendig, weil 'System.in' (= Standardeingabe Tastatur) standardmäßig immer geöffnet ist. </p> <p> Bemerkungen: <ul> <li>Der Einfachheit halber ist die Fehlerbearbeitung sehr primitiv!</li> <li>'^Z' (= 'Strg' + 'Z') beendet die Eingabe (EOF) und liefert 'null' für die Eingabe zurück.</li> <li>Umgekehrt wird 'null' nur bei '^Z' als Eingabe zurückgegeben.</li> <li>EOF ist also äquivalent zur Eingabe von '^Z'.</li> <li>Achtung: 'EOFException' tritt bei der Standardeingabe nicht ein.</li> <li>Zusätzlich wird auch die Eingabe der Zeichenfolge "EOF" als EOF interpretiert (gleichbedeutend mit der Eingabe von '^Z').</li> <li>Bei einem allgemeinen Eingabefehler ('IOException') wird 'null' als Eingabe definiert (das ist gleichbedeutend mit EOF).</li> </ul> </p> <hr /> @since August 2000 @version Juli 2002 (Zeichenkette mit variabler Länge) @version <br />Juni 2007 (Refaktorierung) @version <br />September 2012 (Refaktorierung - lesenEingabe) @version <br />Juli 2014 (Verschieben in Paket 'daoKlassen') @see Schueler @see at.beringer.oopBuch.einAusgabe.ErfassenSchreiben @see at.beringer.oopBuch.jdbc.ErfassenSchreibenDB @see DAOlesenSchueler @author Beringer Alfred */ public class DAOerfassenSchueler { // ------------------------------------------------------------------------- // Klassenkonstante // ------------------------------------------------------------------------- /** Zeichenkette, die das Ende der Tastatureingabe definiert. <p> Dient als zusätzliche EOF-Kennzeichnung (zusätzlich zur Eingabe von '^Z') </p> */ private static final String EOF = "EOF"; // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- /** Datenobjekt für die zu erfassenden Daten */ private Schueler schueler; private boolean eof = false; /** Verbindungsobjekt zur Datei (= Tastatur) */ private BufferedReader tastatur = new BufferedReader( new InputStreamReader(System.in)); // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert die Daten des erfassten Datensatzes. @return Datenobjekt mit den Daten des erfassten Datensatzes */ public Schueler getSchueler() { return schueler; } // ------------------------------------------------------------------------- /** Zeigt EOF (= "Ende der Datei") an (nachdem alle Datensätze erfasst wurden). @return true, wenn das Ende der Datenerfassung erreicht wurde */ public boolean getEof() { return eof; } // ------------------------------------------------------------------------- // Instanzmethoden für Dateiverarbeitung // ------------------------------------------------------------------------- /** Lesen des nächsten Datensatzes. Prüfen und aufbereiten der Eingabedaten. Erstellen eines Schülerobjekts. <p> Die Datenfelder werden (entsprechend dem Satzaufbau) der Reihe nach über die Tastatur eingegeben (erfasst) und - soweit möglich - geprüft.<br /> Bei einem Fehler wird kein Schülerobjekt erstellt und die Erfassung des Datensatzes abgebrochen. </p> @return true, wenn die Erfassung des Datensatzes erfolgreich war */ public boolean lesen() { String eingabe; String name; float notenschnitt; String klasse; // -------------------- // 1. Datenfeld (Name - Zeichenkette mit variabler Länge) eingabe = lesenEingabe("Bitte Schülernamen eingeben (Ende: " + EOF + " oder ^Z):"); if (eof) { return true; // EOF ist kein Fehler } name = eingabe; // -------------------- // 2. Datenfeld (Notendurchschnitt - Zahl) eingabe = lesenEingabe("Bitte Notendurchschnitt eingeben:"); if (eof) { // Bei zu frühem EOF wird kein Datensatz erstellt return true; // EOF ist kein Fehler } try { notenschnitt = Float.parseFloat(eingabe); } catch (NumberFormatException fehler) { System.out.println("Falscher Notendurchschnitt: " + eingabe); return false; } // -------------------- // 3. Datenfeld (Klassenbezeichnung - Zeichenkette mit fixer Länge) eingabe = lesenEingabe("Bitte Klasse eingeben (max. " + Schueler.KLASSELEER.length() + " Zeichen):"); if (eof) { // Bei zu frühem EOF wird kein Datensatz erstellt return true; // EOF ist kein Fehler } klasse = eingabe; // -------------------- // Erfasste Daten sind korrekt -> Objekt für Datensatz instanzieren schueler = new Schueler(); schueler.setName(name); schueler.setNotenschnitt(notenschnitt); schueler.setKlasse(klasse); return true; } // ------------------------------------------------------------------------- // Private Instanzmethoden // ------------------------------------------------------------------------- /** Liest eine Zeile von der Tastatur. <p> Eingabe: alle Zeichen bis zur 'Return'- bzw. 'Enter'-Taste. </p> <p> Ende der Eingabe durch die Zeichenfolge "EOF" oder durch '^Z' (= 'Strg' + 'Z'). </p> Bemerkungen: <ul> <li>'EOFException' tritt bei der Standardeingabe nicht ein!</li> <li>'^Z' = EOF-Kennung bei Konsoleneingabe, d.h.: EOF ist äquivalent zur Eingabe von '^Z'.</li> <li>Eingabe von '^Z' liefert 'null' für die Eingabe.</li> <li>EOF ist also gleichbedeutend mit 'null' für die Eingabe.</li> </ul> @param eingabeaufforderung Eingabeaufforderung @return eingegebene Daten oder 'null' (bei Eingabe von '^Z') */ private String lesenEingabe(String eingabeaufforderung) { String eingabe; System.out.println(eingabeaufforderung); try { eingabe = tastatur.readLine(); } catch (IOException fehler) { eingabe = null; // Datenerfassung beenden (EOF setzen) System.out.println("Fehler beim Erfassen: " + fehler.getMessage()); } // EOF prüfen: if ( (eingabe == null) || (eingabe.equals(EOF)) ) { eof = true; System.out.println("EOF"); // diese Ausgabe dient nur zum Testen } return eingabe; } } |
6.1.2.2 Klasse DAOschreibenSchueler
für Speichern von Daten in einer Datei
Klasse DAOschreibenSchueler |
---|
/* * DAOschreibenSchueler.java */ package at.beringer.oopBuch.daoKlassen; import java.io.*; import at.beringer.oopBuch.modelKlassen.Schueler; /** DAO-Klasse für das Schreiben von Schülerdaten in eine Datei (Nichtstandarddatei). <p> Die Schülerdaten sind die Attribute eines 'Schueler'-Objekts. </p> <p> Bemerkungen: <ul> <li>Der Einfachheit halber ist die Fehlerbearbeitung sehr primitiv!</li> <li>Die Konsolausgaben bei Fehlern dienen nur zur Kontrolle und sollten durch Erzeugung eigener Fehlerobjekte ersetzt werden.</li> </ul> </p> <p> Satzspiegel der Schülerdatei: <pre> --------------------------------------------------------------- Stellen von - bis (Länge) Datenfeld --------------------------------------------------------------- 1 - 4 (4) .... LÄNGE DES NACHFOLGENDEN NAMENS (int) 5 - xx (var) ... NAME (variable Länge) (4) .... NOTENDURCHSCHNITT (float) (7) .... KLASSE (fixe Länge) </pre> </p> <hr /> @since August 2000 @version Juli 2002 (Zeichenkette mit variabler Länge) @version <br />Juni 2007 (Refaktorierung) @version <br />Juli 2012 (FileOutputStream-Objekt als lokale Variable) @version <br />Juli 2014 (Verschieben in Paket 'daoKlassen') @see Schueler @see at.beringer.oopBuch.einAusgabe.ErfassenSchreiben @see at.beringer.oopBuch.einAusgabeSwing.ErfassenSchreibenV @see DAOschreibenDBSchueler @see DAOausgebenSchueler @author Beringer Alfred */ public class DAOschreibenSchueler { // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- /** Datenobjekt für die zu schreibenden Daten */ private Schueler schueler; /** Verbindungsobjekt zur Datei */ private DataOutputStream ausgabesatz; // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Setzt die Daten für den zu schreibenden Datensatz. @param schueler Datenobjekt mit den Daten des zu schreibenden Datensatzes */ public void setSchueler(Schueler schueler) { this.schueler = schueler; } // ------------------------------------------------------------------------- // Instanzmethoden für Dateiverarbeitung // ------------------------------------------------------------------------- /** Öffnet eine (Nichtstandard-)Datei zum Schreiben. @param dateiname Name der zu öffnenden Datei (als Zeichenkette) @return true, wenn das Öffnen der Datei erfolgreich war */ public boolean oeffnen(String dateiname) { FileOutputStream ausgabedatei; // entfällt bei Schachtelung try { ausgabedatei = new FileOutputStream(dateiname); ausgabesatz = new DataOutputStream(ausgabedatei); // Schachtelung ist möglich: // ausgabesatz = new DataOutputStream(new FileOutputStream(dateiname)); } catch (IOException fehler) { System.err.println("Fehler beim Öffnen der Datei: " + dateiname + " " + fehler.getMessage()); // nur zum Testen return false; } return true; } // ------------------------------------------------------------------------- /** Schreiben eines neuen Datensatzes in die Datei. <p> Die Datenfelder werden (entsprechend dem Satzaufbau) der Reihe nach in die Datei geschrieben. </p> <p> Satzaufbau für die Daten eines Schülers: <ol> <li>Länge (= Anzahl der Zeichen) des nachfolgenden Namens (int-Zahl)</li> <li>Name (Zeichenkette mit variabler Länge)</li> <li>Notendurchschnitt (float-Zahl)</li> <li>Klasse (Zeichenkette mit fixer Länge)</li> </ol> </p> @return true, wenn das Schreiben des Datensatzes erfolgreich war */ public boolean schreiben() { try { // Speichern der Länge des 1. Datenfeldes ausgabesatz.writeInt(schueler.getName().length()); // 1. Datenfeld (Name - Zeichenkette mit variabler Länge) ausgabesatz.writeBytes(schueler.getName()); /* Bem.: 'writeBytes' schreibt ASCII-Zeichen (8 Bit) 'writeChars' schreibt Unicode-Zeichen (16 Bit) */ // 2. Datenfeld (Notendurchschnitt - Zahl) ausgabesatz.writeFloat(schueler.getNotenschnitt()); // 3. Datenfeld (Klasse - Zeichenkette mit fixer Länge) ausgabesatz.writeBytes(schueler.getKlasse()); } catch (IOException fehler) { System.err.println("Fehler beim Schreiben des Datensatzes: " + fehler.getMessage()); // nur zum Testen return false; } return true; } // ------------------------------------------------------------------------- /** Schließt die Datei. @return true, wenn das Schließen der Datei erfolgreich war */ public boolean schliessen() { try { ausgabesatz.close(); } catch (Exception fehler) { System.err.println("Fehler beim Schließen der Datei: " + fehler.getMessage()); // nur zum Testen return false; } return true; } } |
6.1.2.3 Klasse DAOlesenSchueler
für Lesen von Daten aus einer Datei
Klasse DAOlesenSchueler |
---|
/* * DAOlesenSchueler.java */ package at.beringer.oopBuch.daoKlassen; import java.io.*; import at.beringer.oopBuch.modelKlassen.Schueler; /** DAO-Klasse für das Lesen von Schülerdaten aus einer Datei (Nichtstandarddatei). <p> Die Schülerdaten werden in 'Schueler'-Objekten aufbereitet. </p> <p> Bemerkungen: <ul> <li>Der Einfachheit halber ist die Fehlerbearbeitung sehr primitiv!</li> <li>Die Konsolausgaben bei Fehlern dienen nur zur Kontrolle und sollten durch Erzeugung eigener Fehlerobjekte ersetzt werden.</li> </ul> </p> <p> Satzspiegel der Schülerdatei: <pre> --------------------------------------------------------------- Stellen von - bis (Länge) Datenfeld --------------------------------------------------------------- 1 - 4 (4) .... LÄNGE DES NACHFOLGENDEN NAMENS (int) 5 - xx (var) ... NAME (variable Länge) (4) .... NOTENDURCHSCHNITT (float) (7) .... KLASSE (fixe Länge) </pre> </p> <hr /> @since August 2000 @version Juli 2002 (Zeichenkette mit variabler Länge) @version <br />Juni 2007 (Refaktorierung) @version <br />Juli 2012 (FileInputStream-Objekt als lokale Variable) @version <br />Juli 2014 (Verschieben in Paket 'daoKlassen') @see Schueler @see at.beringer.oopBuch.einAusgabe.LesenAusgeben @see at.beringer.oopBuch.einAusgabeSwing.LesenAusgebenStringV @see DAOlesenDBSchueler @see DAOerfassenSchueler @author Beringer Alfred */ public class DAOlesenSchueler { // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- /** Datenobjekt für die zu lesenden Daten */ private Schueler schueler; private boolean eof = false; /** Verbindungsobjekt zur Datei */ private DataInputStream eingabesatz; // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert die Daten des gelesenen Datensatzes. @return Datenobjekt mit den Daten des gelesenen Datensatzes */ public Schueler getSchueler() { return schueler; } // ------------------------------------------------------------------------- /** Zeigt EOF (= "Ende der Datei") an (nachdem alle Datensätze gelesen wurden). @return true, wenn das Ende der Datei erreicht wurde */ public boolean getEof() { return eof; } // ------------------------------------------------------------------------- // Instanzmethoden für Dateiverarbeitung // ------------------------------------------------------------------------- /** Öffnet eine (Nichtstandard-)Datei zum Lesen. @param dateiname Name der zu öffnenden Datei (als Zeichenkette) @return true, wenn das Öffnen der Datei erfolgreich war */ public boolean oeffnen(String dateiname) { FileInputStream eingabedatei; // entfällt bei Schachtelung try { eingabedatei = new FileInputStream(dateiname); eingabesatz = new DataInputStream(eingabedatei); // Schachtelung ist möglich: // eingabesatz = new DataInputStream(new FileInputStream(dateiname)); } catch (IOException fehler) { System.err.println("Fehler beim Öffnen der Datei: " + dateiname + " " + fehler.getMessage()); // nur zum Testen return false; } return true; } // ------------------------------------------------------------------------- /** Lesen des nächsten Datensatzes aus der Datei - alle Attribute eines Schülerobjekts sind nebeneinander ohne Abstand gespeichert. Aufbereiten der Eingabedaten. Erstellen eines Schülerobjekts. <p> Die Datenfelder werden (entsprechend dem Satzaufbau) der Reihe nach aus der Datei gelesen.<br /> Bei einem IO-Fehler wird kein Schülerobjekt erstellt. </p> <p> Hinweis: Die Daten werden nicht mehr geprüft. </p> <p> Satzaufbau für die Daten eines Schülers: <ol> <li>Länge (= Anzahl der Zeichen) des nachfolgenden Namens (int-Zahl)</li> <li>Name (Zeichenkette mit variabler Länge)</li> <li>Notendurchschnitt (float-Zahl)</li> <li>Klasse (Zeichenkette mit fixer Länge)</li> </ol> </p> @return true, wenn das Lesen des Datensatzes erfolgreich war */ public boolean lesen() { String name; float notenschnitt; String klasse; // byte-Array für eine Zeichenkette mit fixer Länge byte[] bytesKlasse = new byte[Schueler.KLASSELEER.length()]; // byte-Array für eine Zeichenkette mit variabler Länge byte[] bytesVar; try { // Länge des 1. Datenfeldes bytesVar = new byte[eingabesatz.readInt()]; // 1. Datenfeld (Name - Zeichenkette mit variabler Länge) eingabesatz.read(bytesVar); name = new String(bytesVar); // 2. Datenfeld (Notendurchschnitt - Zahl) notenschnitt = eingabesatz.readFloat(); // 3. Datenfeld (Klassenbezeichnung - Zeichenkette mit fixer Länge) eingabesatz.read(bytesKlasse); klasse = new String(bytesKlasse); } catch (EOFException exc) { eof = true; System.out.println("EOF"); // diese Ausgabe dient nur zum Testen return true; // EOF ist kein Fehler } catch (IOException fehler) { System.err.println("Fehler beim Lesen des Datensatzes: " + fehler.getMessage()); // nur zum Testen return false; } // -------------------- // Daten wurden korrekt gelesen -> Objekt für Datensatz instanzieren schueler = new Schueler(); schueler.setName(name); schueler.setNotenschnitt(notenschnitt); schueler.setKlasse(klasse); return true; } // ------------------------------------------------------------------------- /** Schließt die Datei. @return true, wenn das Schließen der Datei erfolgreich war */ public boolean schliessen() { try { eingabesatz.close(); } catch (Exception fehler) { System.err.println("Fehler beim Schließen der Datei: " + fehler.getMessage()); // nur zum Testen return false; } return true; } } |
6.1.2.4 Klasse DAOausgebenSchueler
für die Ausgabe von Daten (Standardausgabe)
Die Ausgabe erfolgt in ein Konsolenfenster am Bildschirm. Nach jeweils 20 Ausgabezeilen (einschließlich einer Überschrift und einer nachfolgenden Leerzeile) wird ein Seitenende angenommen und ein Vorschub auf eine neue Seite simuliert - durch Schreiben einer horizontalen Linie. (Eine tatsächliche Druckerausgabe auf Papier wird in diesem Buch nicht behandelt.)
Klasse DAOausgebenSchueler |
---|
/* * DAOausgebenSchueler.java */ package at.beringer.oopBuch.daoKlassen; import at.beringer.oopBuch.modelKlassen.Schueler; /** DAO-Klasse für das Aufbereiten von Schülerdaten und für das Schreiben dieser Daten auf die Standardausgabe (= Bildschirm). <p> Die Schülerdaten sind die Attribute eines 'Schueler'-Objekts. </p> <p> Aufbereiten von Schülerdaten und formatiert ausgeben in 1 Zeile. </p> <p> Methoden 'oeffnen' und 'schliessen' sind nicht notwendig, weil 'System.out' (= Standardausgabe Bildschirm) standardmäßig immer geöffnet ist. </p> <p> Bemerkungen: <ul> <li>Der Einfachheit halber ist die Fehlerbearbeitung sehr primitiv!</li> <li>Der Einfachheit halber sind die auszugebenden Texte fix codiert (d.h. keine Internationalisierung!).</li> </ul> </p> <hr /> @since August 2009 @version Juli 2014 (Verschieben in Paket 'daoKlassen') @see Schueler @see at.beringer.oopBuch.einAusgabe.LesenAusgeben @see at.beringer.oopBuch.jdbc.LesenDBAusgeben @see DAOausgebenSchuelerString @see DAOschreibenSchueler @author Beringer Alfred */ public class DAOausgebenSchueler { // ------------------------------------------------------------------------- // Klassenkonstante // ------------------------------------------------------------------------- /** Maximale Anzahl Zeilen pro Seite */ private static final int ZZMAX; /** Simulieren "Vorschub auf neue Seite" */ private static final String NEUESEITE; /** Überschrift */ private static final String UEBER; /** Format für die Ausgabezeile */ private static final String F_AB; // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- /** Datenobjekt für die auszugebenden Daten */ private Schueler schueler; /** Zeilenzähler */ private int zz; // ------------------------------------------------------------------------- // Klassenkonstruktor // ------------------------------------------------------------------------- /** Klassenkonstruktor (Klassen-Initialisierungsblock). <p> Die Werte für nicht initialisierte Klassenkonstante könnten von externen Datenquellen geholt werden (z.B. von einer Datei, einer Datenbank oder von einer Properties-Datei). <p> Der Einfachheit halber werden die Werte jedoch fix vorgegeben. </p> */ static { ZZMAX = 5; // Zum Testen mindestens 4 Datensätze erfassen NEUESEITE = "%n___________________________________________________%n%n"; UEBER = "NAME NOTENDURCHSCHNITT KLASSE %n%n"; F_AB = "%-25s %5.2f %s %n"; } // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** Standardkonstruktor. <p> Am Beginn wird das Ende einer Seite simuliert, um auf einfache Art eine Überschrift auf der ersten Seite zu erzwingen. </p> */ public DAOausgebenSchueler() { zz = ZZMAX; } // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Setzt die Daten für den auszugebenden Datensatz. @param schueler Datenobjekt mit den Daten des auszugebenden Datensatzes */ public void setSchueler(Schueler schueler) { this.schueler = schueler; } // ------------------------------------------------------------------------- // Instanzmethoden für Dateiverarbeitung // ------------------------------------------------------------------------- /** Schreibt 1 Zeile mit den gewünschten Schülerdaten. <p> Die Datenfelder werden formatiert ausgegeben. Gegebenenfalls erfolgt ein (simulierter) Seitenvorschub und die Ausgabe einer Überschrift. </p> */ public void schreibenZeile() { if (zz >= ZZMAX) { System.out.printf(NEUESEITE); System.out.printf(UEBER); zz = 2; } System.out.printf(F_AB, schueler.getName(), schueler.getNotenschnitt(), schueler.getKlasse()); zz = zz + 1; } } |
6.1.3 Anwendungsprogramme
Programmklasse ProgrammErfassenSchreiben |
---|
/* * ProgrammErfassenSchreiben.java */ package at.beringer.oopBuch.einAusgabe; /** Programmklasse (Applikation) zum Testen der Klasse 'ErfassenSchreiben'. <p> Der Dateiname wird beim Aufruf als Parameter übergeben. </p> <hr /> @since August 2007 @see ErfassenSchreiben @author Beringer Alfred */ public class ProgrammErfassenSchreiben { // ------------------------------------------------------------------------- /** Der Einstiegspunkt für die Anwendung. @param args Kommandozeilenparameter - Name der Ausgabedatei */ public static void main(String[ ] args) { if (args == null || args.length == 0) { // Fehlt der Dateiname, wird die Datei fix vorgegeben: args = new String[ ] { "schueler.dat" }; } ErfassenSchreiben app = new ErfassenSchreiben(); app.start(args[0]); // Dateiname als Parameter übergeben } } |
Programmklasse ProgrammLesenAusgeben |
---|
/* * ProgrammLesenAusgeben.java */ package at.beringer.oopBuch.einAusgabe; /** Programmklasse (Applikation) zum Testen der Klasse 'LesenAusgeben'. <p> Der Dateiname wird beim Aufruf als Parameter übergeben. </p> <hr /> @since August 2007 @see LesenAusgeben @author Beringer Alfred */ public class ProgrammLesenAusgeben { // ------------------------------------------------------------------------- /** Der Einstiegspunkt für die Anwendung. @param args Kommandozeilenparameter - Name der Eingabedatei */ public static void main(String[ ] args) { if (args == null || args.length == 0) { // Fehlt der Dateiname, wird die Datei fix vorgegeben: args = new String[ ] { "schueler.dat" }; } LesenAusgeben app = new LesenAusgeben(); app.start(args[0]); // Dateiname als Parameter übergeben } } |
6.1.3.1 Anwendungsklasse für Daten erfassen und speichern
Klasse ErfassenSchreiben |
---|
/* * ErfassenSchreiben.java */ package at.beringer.oopBuch.einAusgabe; import at.beringer.oopBuch.daoKlassen.DAOerfassenSchueler; import at.beringer.oopBuch.daoKlassen.DAOschreibenSchueler; /** Einfache Konsolenanwendung für Erfassen (Lesen) von Daten über die Standardeingabe (= Tastatur) und Schreiben der Daten in eine Datei. <p> Der Dateiname wird beim Aufruf als Parameter übergeben. </p> <hr /> @since August 2000 @version Juli 2002 (Zeichenkette mit variabler Länge) @version <br />August 2007 (eigene Programmklasse) @see DAOerfassenSchueler @see DAOschreibenSchueler @see ProgrammErfassenSchreiben @see at.beringer.oopBuch.jdbc.ErfassenSchreibenDB @see LesenAusgeben @author Beringer Alfred */ public class ErfassenSchreiben { // ------------------------------------------------------------------------- // Instanzmethoden // ------------------------------------------------------------------------- /** Öffentliche Methode zum Starten der Applikation. @param dateiname Name der Ausgabedatei (als Zeichenkette) */ public void start(String dateiname) { DAOerfassenSchueler eingabedaten = new DAOerfassenSchueler(); DAOschreibenSchueler ausgabedaten = new DAOschreibenSchueler(); boolean ok; // Am Beginn der Applikation Datei öffnen if (!ausgabedaten.oeffnen(dateiname)) { System.err.println("Fehler beim Öffnen der Datei " + dateiname + " ---> Ende"); return; } ok = eingabedaten.lesen(); // Lesen Standardeingabe (Tastatur) while (!eingabedaten.getEof()) { if (ok) { // nur zum Testen: System.out.println(eingabedaten.getSchueler()); // Daten übernehmen (Datenobjekt füllen mit den Eingabedaten) ausgabedaten.setSchueler(eingabedaten.getSchueler()); ausgabedaten.schreiben(); // Datensatz schreiben } else { System.err.println("Fehler beim Erfassen!"); } ok = eingabedaten.lesen(); // Lesen Standardeingabe (Tastatur) } // Am Ende der Applikation Datei schließen ausgabedaten.schliessen(); } } |
6.1.2.3 Anwendungsklasse für Daten lesen und ausgeben
Klasse LesenAusgeben |
---|
/* * LesenAusgeben.java */ package at.beringer.oopBuch.einAusgabe; import at.beringer.oopBuch.daoKlassen.DAOlesenSchueler; import at.beringer.oopBuch.daoKlassen.DAOausgebenSchueler; /** Einfache Konsolenanwendung für Lesen von Daten aus einer Datei und Ausgeben (Schreiben) der Daten auf die Standardausgabe (= Bildschirm). <p> Der Dateiname wird beim Aufruf als Parameter übergeben. </p> <hr /> @since August 2000 @version Juli 2002 (Zeichenkette mit variabler Länge) @version <br />August 2007 (eigene Programmklasse) @see DAOlesenSchueler @see DAOausgebenSchueler @see ProgrammLesenAusgeben @see at.beringer.oopBuch.jdbc.LesenDBAusgeben @see ErfassenSchreiben @author Beringer Alfred */ public class LesenAusgeben { // ------------------------------------------------------------------------- // Instanzmethoden // ------------------------------------------------------------------------- /** Öffentliche Methode zum Starten der Applikation. @param dateiname Name der Eingabedatei (als Zeichenkette) */ public void start(String dateiname) { DAOlesenSchueler eingabedaten = new DAOlesenSchueler(); DAOausgebenSchueler ausgabedaten = new DAOausgebenSchueler(); boolean ok; // Am Beginn der Applikation Datei öffnen if (!eingabedaten.oeffnen(dateiname)) { System.err.println("Fehler beim Öffnen der Datei " + dateiname + " ---> Ende"); return; } ok = eingabedaten.lesen(); // Lesen Datensatz while (!eingabedaten.getEof()) { if (ok) { // Daten übernehmen (Datenobjekt füllen mit den Eingabedaten) ausgabedaten.setSchueler(eingabedaten.getSchueler()); ausgabedaten.schreibenZeile(); // 1 Zeile schreiben } else { System.err.println("Fehler beim Lesen!"); } ok = eingabedaten.lesen(); // Lesen Datensatz } // Am Ende der Applikation Datei schließen eingabedaten.schliessen(); } } |
6.1.4 Allgemeines Klassendiagramm für die DAO-Klassen
Das folgende Klassendiagramm zeigt allgemein die DAO-Klassen (nicht nur spezifisch für Java). Beispielsweise steht Standardeingabe
für die Java-Streamklasse BufferedReader
und Standardausgabe
für das Java-Objekt 'System.out'
. Die Klassenattribute der Klasse DAOausgeben
(wie z.B. ZZMAX
) fehlen, weil diese Klasse ja sehr individuell von den Benutzerwünschen abhängt.
Die Klasse Schueler
steht beispielhaft für eine Datenklasse, die Methoden getSchueler
und setSchueler
stehen beispielhaft für die Methoden getDatenObjekt
bzw. setDatenobjekt
.

- Weiter
- zu den Java-Klassenbeispielen von Kapitel 7 (GUI)
- zu Kapitel 8 (JDBC)
- zu den C#-Klassenbeispielen von Kapitel 9.19.1 (Exceptions)
- zu den C#-Klassenbeispielen von Kapitel 10 (Ein-/Ausgabe von Daten)
- zu Kapitel 12 (PL/I)
- zu Kapitel 13 (Reservierte Worte)
- zu Kapitel 8 (JDBC)
- Zurück
- zum Anfang dieses Kapitels
- zum Inhaltsverzeichnis
- zu Kapitel 1
- zu den Klassenbeispielen von Kapitel 2
- zur Parameterübergabe (Kapitel 2.7.1)
- zu Kapitel 3
- zu den Klassenbeispielen von Kapitel 4
- zu den Java-Klassenbeispielen von Kapitel 5.19.1 (Exceptions)
- zum Inhaltsverzeichnis
- Zur
- Java-Dokumentation der Java-Beispiele