1 / 73

Modellierung und Programmierung 2

2. Interfaces vs. abstrakte Klassen. Vorteile von InterfacesKlassen k?nnen mehrere Interfaces implementierenexistierende Klassen k?nnen einfach um die Implementierung eines Interfaces erweitert werdeneinfache Deklaration von typ?bergreifenden FunktionenNachteile von Interfaces?nderung des Inter

ohio
Télécharger la présentation

Modellierung und Programmierung 2

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


    1. Modellierung und Programmierung 2 Professur für Angewandte Telematik / e-Business Institut für Informatik Universität Leipzig Stiftungsprofessur der DTAG info@ebus.informatik.uni-leipzig.de www.lpz-ebusiness.de +49 (341) 97 323 30

    2. 2 Interfaces vs. abstrakte Klassen Vorteile von Interfaces Klassen können mehrere Interfaces implementieren existierende Klassen können einfach um die Implementierung eines Interfaces erweitert werden einfache Deklaration von typübergreifenden Funktionen Nachteile von Interfaces Änderung des Interfaces muss in allen implementierenden Klassen nachvollzogen werden Das Objekt KANN etwas Vorteile von abstrakten Klassen ermöglichen die Vererbung von implementierten Methoden können einfach um zusätzliche Methoden erweitert werden (sofern diese bereits implementiert sind) Nachteile von abstrakten Klassen Vererbungshierarchie erlaubt nur eine Oberklasse Klassenhierarchie u.U. schwierig nachträglich änderbar Das Objekt IST EIN…

    3. 3 Entwurfsmuster Im objektorientierten Entwurf existieren für viele häufig wiederkehrende Detailanforderungen allgemeine Lösungen, sog. Entwurfsmuster (Design Patterns): zur Realisierung bestimmter Objektstrukturen (z.B. Singleton, Factory, Composite, ...) zur Interaktion von Objekten mit bestimmten Verhaltensweisen (z.B. Iterator, Observer, Transaction, ...) zur Kooperation und Entkopplung von Systemkomponenten (z.B. Facade, Adapter, Model-View-Controller, ...) Ziel: effektive Anwendung von OO-Konzepten

    4. 4 Literatur: Entwurfsmuster Entwurfsmuster von Kopf bis Fuß, O'Reilly 2005 Erich Gamma et al.: Design Patterns. Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995 Stephen Stelting, Olav Massen: Applied Java Patterns. Prentice Hall, 2001

    5. 5

    6. 6

    7. public class Kunde { private enum Status {NEUKUNDE, KUNDE, SAMMELBESTELLER} private Status status; public String[] gueltigeZahlungsweisen() { switch (status) { case NEUKUNDE: // Zahlungsweisen für Neukunden break; case KUNDE: // Zahlungsweisen für Altkunden break; case SAMMELBESTELLER: // Zahlungsweisen für Sammelbesteller } } 7

    8. public int berechneRabatt() { switch (status) { case NEUKUNDE: // Rabatt für Neukunden break; case KUNDE: // Rabatt für Altkunden break; case SAMMELBESTELLER: // Rabatt für Sammelbesteller } } 8

    9. 9

    10. Übernahme einer britischen Firma… Neue Geschäftsregeln: Kunden in Großbritannien erhalten natürlich eine englische Rechnung. Für Kunden in Großbritannien ist die Zahlungsweise "Scheck" nicht zugelassen. 10

    11. 11

    12. 12

    13. (schlechte) erste Idee: Vererbung 13

    14. Was erbt wirklich voneinander? 14

    15. 15

    16. 16

    17. 17

    18. Das Strategy-Muster 18

    19. Strategy Vorteil des Strategy-Musters: Welcher Algorithmus (von mehreren möglichen) genau verwendet wird, wird zur Laufzeit entschieden. Über eine set-Methode kann die modellierte Eigenschaft später geändert werden ? der Algorithmus ändert sich mit. Die Algorithmen sind in getrennten Klassen programmiert, Änderungen werden so leichter. Mehrfachverzweigung (case…) wird vermieden Neu gegenüber bisheriger Modellierung: Unterschied fachliche Klassen / technische Klassen 19

    20. Das Strategy-Muster – ein Beispiel 20

    21. Beispiel: Kontext public class StringCompressor { // die Variable für die Strategie private Compressor compressor; private String text; public StringCompressor(Compressor compressor ) { this.compressor = compressor; } String compress(String text) { // uebergib dem Komprimierer die Aufgabe // (siehe spätere Folie) } } 21

    22. Das Strategy-Muster 22

    23. Beispiel: Interface Strategie public interface Compressor { // Methode zum Komprimieren String compress (String s); } 23

    24. Das Strategy-Muster 24

    25. Beispiel: konkrete Strategie public class ZIPCompressor implements Compressor { // ZIP - Verfahren zum Komprimieren public String compress (String text) { // komprimiere mittels ZIP – Verfahren: text_gepackt= … return text_gepackt; } } 25

    26. Aufruf in der Klasse StringCompressor if (text.length() < 1000000) compressor = new Compressor (new ZIPCompressor()); else compressor = new Compressor (new HuffmanCodeCompressor()); String gepackt = compressor.compress(text); 26

    27. Die Rechnung bitte… 27

    28. Geschäftsregeln für Rechnung Rechnungen basieren auf einem einheitlichen "Grundtext". Davon gibt es einen für eine Erstrechnung, eine Zahlungserinnerung, und eine Sammelrechnung. Dem werden ggf. weitere Texte hinzugefügt: Wenn das Kundenkonto ein Guthaben aufweist, wird beschrieben, wie dieses auf den Rechnungsbetrag angerechnet wird. 3 Wochen vor Jahresende wird der Kunde darauf hingewiesen, dass die Rechnung noch in diesem Jahr bezahlt werden sollte, um besondere Steuervorteile nutzen zu können. Wenn die Rechnungsadresse von der Lieferadresse abweicht, wird dies in der Rechnung erwähnt. … und noch etwa 100 weitere solche Regeln. 28

    29. (schlechte) erste Idee 29

    30. 30

    31. Wir nehmen ein Sammelrechnung- Objekt. Wir fügen diesem lt. Geschäftsregel einen Zusatz hinzu. Das neue Objekt enthält das bisherige. Das neue Objekt ist selbst wieder eine Rechnung. 31

    32. … dann noch einen Zusatz … und noch einen… 32

    33. 33

    34. 34

    35. 35

    36. Decorator-Muster allgemein 36

    37. 37

    38. 38

    39. 39

    40. 40

    41. 41

    42. 42

    43. 43

    44. 44

    45. Aufruf 45

    46. eine Anwendung des decorator-Musters streams 46

    47. 47 Exkurs: Das Paket Paket java.io

    48. 48 Dateisystem: Dateien Datenspeicherung auf Festplatte, CD, DVD etc. in Dateisystemen aus Dateien (enthalten eigentliche Daten) und Verzeichnisstruktur (organisiert Dateien) Dateien haben Attribute Name, Länge, Datum etc. Verzeichnisstruktur organisiert Dateien Baumstruktur

    49. 49 Modellierung des Dateisystems in Java mit Objekten der Klasse java.io.File zum Anlegen, Öffnen, Schließen und Löschen von Dateien Anlegen und Löschen von Verzeichnissen Abfragen/Setzen von Informationen über Dateien und Verzeichnisse Blättern in der Verzeichnishierarchie nicht zum Lesen und Schreiben in Dateien! wird mit Streams realisiert Beispiel: Länge ausgeben, wenn "java" existiert und eine Datei (kein Verzeichnis) ist File datei = new File("java"); if (datei.exists() && datei.isFile()) { System.out.println(datei.length() + " Bytes"); }

    50. 50 präzise betrachtet, modelliert ein File-Objekt einen Pfad, der eine Datei/ein Verzeichnis identifiziert u.a. mit folgenden Konstruktoren instanziierbar: aus einem String: public File(String pathname) aus einem bereits modellierten Pfad und einem anzuhängenden String: public File(File parent, String child) aus zwei Strings: public File(String parent, String child) weitere Möglichkeiten ? Java API Specification Anlegen eines File-Objekts

    51. 51 Format von Pfadnamen ist plattformspezifisch Verzeichnis-Trennzeichen (z.B. Windows: \; Unix: /) public static final String separator Wurzelverzeichnisse (z.B. Windows: A:\, C:\, ...; Unix: /) public static File[] listRoots() Schnittstellen zwischen abstrakter Pfad-Modellierung im File-Objekt und plattformspezifischen Pfadnamen Datei-/Verzeichnisname: public String getName() Pfadname: public String getPath() kanonischer Pfadname: public String getCanonicalPath() übergeordneter Pfad: public String getParent() äquivalente Methoden auch mit Rückgabetyp File, um mit den umgeformten Pfaden in abstrakter Form weiter zu arbeiten ? API Arbeit mit Pfadnamen in File

    52. 52 Methoden zur Abfrage diverser Eigenschaften von durch File identifizierten Dateien/Verzeichnissen: public boolean exists() public boolean canRead() public boolean canWrite() public boolean isFile() public boolean isDirectory() public boolean isHidden() public long length() public long lastModified() public boolean equals(Object o) public int compareTo(File pathname) public String toString() und viele mehr ? Java API Specification Prüfen von Eigenschaften mit File

    53. 53 leere Datei anlegen public boolean createNewFile() Verzeichnis anlegen public boolean mkdir() nur letztes Verzeichnis im Pfad public boolean mkdirs() ggf. incl. Mutterverzeichnisse Datei/Verzeichnis löschen public boolean delete() sofort public void deleteOnExit() erst bei Beendigung der JVM Datei umbenennen public boolean renameTo(File dest) Änderungsdatum setzen public boolean setLastModified(long time) Schreibschutz setzen public boolean setReadOnly() Datei/Verzeichnis-Operationen auf File

    54. 54 wenn das File-Objekt ein Verzeichnis identifiziert: alle im Verzeichnis enthaltene Einträge public String[] list() allen im Verzeichnis enthaltenen Einträge, die bestimmten Filterkriterien entsprechen public String[] list(FilenameFilter filter) Festlegung der Filterkriterien ist dem Entwickler überlassen werden definiert in einem Objekt, das das Interface FilenameFilter implementiert Auflistung von Verzeichnisinhalten

    55. 55 Herausforderungen bei der Datenübertragung verschiedene Datenformate Bytes oder Unicode-Zeichen viele verschiedene Datenquellen und -senken Dateisystem, Datenstrukturen, Netzwerk, andere Threads viele verschiedene Datentypen primitive Typen, Strings, Klassen (eigene oder von Java) viele verschiedene Vor-/Nachverarbeitungsmöglichkeiten puffern, codieren, komprimieren... eigene Lösung dieser Herausforderungen wäre aufwendig, oft redundant und u.U. nicht plattformunabhängig Java I/O is based on the concept of streams. This is the technique used in C++. A stream is a connection between a source or a sink and a program. Bytes flow from the source one at a time into the program and from the program to the sink in the same way. A stream providing input is an input stream. A stream accepting output is an output stream. There are two abstract classes associated with I/O streams. As with all abstract classes they collect in one place all the essential functions that a stream should implement. The two classes are InputStream and OutputStream. as we shall see these two classes stand at the top of two large hierarchies of streams. The philosophy of Java is to provide a vast collection of streams so that the compiler can check that a user is not accidentally misusing a stream by carrying out an illegal operation on it. C in contrast has one stream type FILE*. Visual Basic has three. C++ has more stream classes than these languages but not as many as Java 1.1 which has 58! Classes which inherit from InputStream or OutputStream are based on single byte input or output. If Java used standard ASCII this would be sufficient for character I/O. However in Java, characters are represented by 16 bit Unicode characters. For this reason two further abstract classes Reader and Writer and their associated hierarchies are required to implement character I/O. Java I/O is based on the concept of streams. This is the technique used in C++. A stream is a connection between a source or a sink and a program. Bytes flow from the source one at a time into the program and from the program to the sink in the same way. A stream providing input is an input stream. A stream accepting output is an output stream. There are two abstract classes associated with I/O streams. As with all abstract classes they collect in one place all the essential functions that a stream should implement. The two classes are InputStream and OutputStream. as we shall see these two classes stand at the top of two large hierarchies of streams. The philosophy of Java is to provide a vast collection of streams so that the compiler can check that a user is not accidentally misusing a stream by carrying out an illegal operation on it. C in contrast has one stream type FILE*. Visual Basic has three. C++ has more stream classes than these languages but not as many as Java 1.1 which has 58! Classes which inherit from InputStream or OutputStream are based on single byte input or output. If Java used standard ASCII this would be sufficient for character I/O. However in Java, characters are represented by 16 bit Unicode characters. For this reason two further abstract classes Reader and Writer and their associated hierarchies are required to implement character I/O.

    56. 56 Lösung in Java: Datenströme (Streams) generelle Konstrukte mit der Fähigkeit, Daten von einer Datenquelle zu empfangen Daten an eine Datensenke zu senden ein bestimmter Stream weiß, wie ein bestimmtes Problem (Quellen-/Senkentyp, Datentyp, Verarbeitung) zu lösen ist Java hat Stream-Klassen für verschiedenste Aufgaben Entwickler muss sich nicht um Details kümmern, sondern ruft einfach Methoden wie "lesen" oder "schreiben" auf Streams erlauben i.d.R. nur fortlaufenden Datenzugriff wahlfreier Zugriff bei einigen Streams über Methoden mark() und reset() oder mit Klasse RandomAccessFile möglich ? API

    57. 57 Grundlegende (abstrakte) Stream-Klassen Unterscheidung nach Datenflussrichtung Eingabestreams vs. Ausgabestreams Unterscheidung nach Datenformat Bytestreams lesen/schreiben einzelne Bytes Zeichenstreams lesen/schreiben Unicode-Zeichen vier abstrakte Oberklassen für alle Stream-Arten von Java: für Bytes für Zeichen zur Eingabe InputStream Reader zur Ausgabe OutputStream Writer

    58. 58 Eingabestreams (abstrakt) InputStream Reader int available() boolean ready() liefert Zahl lesbarer Bytes einlesbare Zeichen vorhanden? int read() int read() nächstes Byte lesen nächstes Zeichen lesen liefert 0-255 oder -1 (Ende) liefert 0-65535 oder -1 (Ende) int read(byte[] b) int read(char[] c) Bytes in Array einlesen Zeichen in Array einlesen liefert Zahl gelesener Bytes liefert Zahl gelesener Zeichen void close() void close() Stream schließen Stream schließen (Öffnen der Streams implizit beim Konstruktoraufruf) alle Methoden werfen bei Fehlern java.io.IOException

    59. 59 Ausgabestreams (abstrakt) OutputStream Writer void write(int b) void write(int c) übergebenes Byte schreiben übergebenes Zeichen schreiben (nur untere 8 Bits betrachtet) (nur untere 16 Bits betrachtet) void write(byte[] b) void write(char[] c) Bytes aus Array schreiben Zeichen aus Array schreiben void write(String s) Zeichen aus String schreiben void flush() void flush() gepufferte Bytes schreiben gepufferte Zeichen schreiben void close() void close() Stream schließen Stream schließen (Öffnen der Streams implizit beim Konstruktoraufruf) alle Methoden werfen bei Fehlern java.io.IOException

    60. 60 Eigenschaften von Streams Lesen und Schreiben blockiert Ausführung (des Threads) Methoden warten, bis etwas gelesen oder geschrieben wurde Achtung: falls keine zu lesenden Daten vorliegen, steht read() ! available() blockiert nicht und kann zur Prüfung verwendet werden, um zu lesende Daten vorliegen Streams sollten mit close() geschlossen werden. The mechanism shown on the previous slide means that methods read() and write() are rarely used explicitly in programs. They are usually invoked indirectly by methods of a subclass of InputStream or OutputStream. Regardless of whether they are explicitly called or not, calls to read() and write() cause a thread to block. In the case of an input operation a thread which calls read() may block because the data it requires is not yet available. The method available() returns an int which gives the number of bytes which are available for reading. Threads that wish to avoid waiting for input can make use of this method by not invoking read() when there are no bytes available.. All streams require buffer space etc. When a stream is no longer required this buffer space can be released. All I/O streams implement a method close() which will achieve this. In order to optimise disk I/O, streams will buffer data. Typically an output stream will hold data in main memory until enough has been generated to make it worthwhile to write to disk. The programmer can cause buffers to be emptied on demand by invoking the method flush(). The mechanism shown on the previous slide means that methods read() and write() are rarely used explicitly in programs. They are usually invoked indirectly by methods of a subclass of InputStream or OutputStream. Regardless of whether they are explicitly called or not, calls to read() and write() cause a thread to block. In the case of an input operation a thread which calls read() may block because the data it requires is not yet available. The method available() returns an int which gives the number of bytes which are available for reading. Threads that wish to avoid waiting for input can make use of this method by not invoking read() when there are no bytes available.. All streams require buffer space etc. When a stream is no longer required this buffer space can be released. All I/O streams implement a method close() which will achieve this. In order to optimise disk I/O, streams will buffer data. Typically an output stream will hold data in main memory until enough has been generated to make it worthwhile to write to disk. The programmer can cause buffers to be emptied on demand by invoking the method flush().

    62. 62 konkrete Streams Unterklassen zur Erfüllung bestimmter Aufgaben Lesen/Schreiben aus/in Datenquellen/-senken Verwendung anderer Streams als Datenquellen/-senken Vor/-Nachverarbeitung der Daten im Stream Ein/-Ausgabe verschiedener Datentypen i.d.R. müssen mehrere (aber nicht unbedingt alle) dieser Aufgaben gelöst werden

    63. 63 Streams zum Medien-Zugriff Zugriff auf verschiedene Quellen/Senken Lesen/Schreiben aus/in Dateien im Dateisystem FileInputStream FileReader FileOutputStream FileWriter Lesen/Schreiben aus/in Datenstrukturen im Hauptspeicher ByteArrayInputStream CharArrayReader ByteArrayOutputStream CharArrayWriter Lesen/Schreiben aus/in Netzwerken später behandelt

    65. 65 Verwendung von Medienstreams Beispiel: FileOutputStream Konstruktor öffnet die Datei und überschreibt ggf. zuvor bestehende Datei FileOutputStream(File file) FileOutputStream(String name) hängt bei append==true an Datei an, überschreibt sonst ggf. FileOutputStream(File file, boolean append) FileOutputStream(String name, boolean append) (alle können FileNotFoundException werfen) implementiert Methoden vom abstrakten OutputStream write (Byte oder Byte-Array schreiben), flush (Puffer leeren), etc. arbeiten auf der vom Stream gekapselten Datei

    67. 67 Streams zur Verknüpfung von Streams Wandeln zwischen Byte- und Unicode-Streams: InputStreamReader OutputStreamWriter Lesen von Daten aus mehreren Streams nacheinander SequenceInputStream

    68. 68 Streams zur Filterung von Daten Verarbeitung oder Veränderung ("Filterung") von Daten Zwischenspeicherung von Daten in einem Puffer BufferedInputStream BufferedReader BufferedOutputStream BufferedWriter Lesen/Schreiben von Daten mit (De-)Komprimierung java.util.zip.InflaterInputStream java.util.zip.DeflaterOutputStream Lesen/Schreiben von Daten mit Ent-/Verschlüsselung javax.crypto.CipherInputStream javax.crypto.CipherOutputStream

    71. Text packen und speichern

    72. 72 Verw. von Verknüpfungs-/Filterstreams Beispiel: BufferedOutputStream Konstruktor nimmt zugrundeliegenden Stream und ggf. Puffergröße entgegen BufferedOutputStream(OutputStream out) BufferedOutputStream(OutputStream out, int size) Methoden wie abstrakter OutputStream write (Byte oder Byte-Array schreiben), flush (Puffer leeren), etc. Daten werden in objektinternem Puffer zwischengespeichert bei Erreichen der angegebenen Größe (oder Vorgabe 512 Bytes): Pufferinhalt wird in den zugrundeliegenden OutputStream geschrieben; Pufferinhalt wird gelöscht Zyklus beginnt von vorn

    73. ZipOutputStream z = new ZipOutputStream( new BufferedOutputStream( new FileOutputStream(f)))); - ein zweifach dekorierter FileOutputStream 73

    74. 74 Implementierung eigener Stream-Filter Oberklassen zur Definition eigener Filter FilterInputStream FilterReader FilterOutputStream FilterWriter eigene Filter bekommen im Konstruktor den zugrundeliegenden Stream übergeben zugrundeliegender Stream wird mit super(stream); zur Verknüpfung an Oberklasse weitergegeben nötige Methoden der Oberklasse sind zu überschreiben.

More Related