JAVA & Objektorientiertes Programmieren 2
Erweiterung der ersten Kartei
Erweiterung der ersten Kartei
Fichier Détails
Cartes-fiches | 203 |
---|---|
Langue | Deutsch |
Catégorie | Informatique |
Niveau | Université |
Crée / Actualisé | 19.01.2017 / 09.01.2024 |
Lien de web |
https://card2brain.ch/box/20170119_java_objektorientiertes_programmieren_2
|
Intégrer |
<iframe src="https://card2brain.ch/box/20170119_java_objektorientiertes_programmieren_2/embed" width="780" height="150" scrolling="no" frameborder="0"></iframe>
|
Was bedeutet FCoI?
Favor composition over inheritance
Was bedeutet FCoI?
Im Zweifelsfall: Die Komposition ist der Vererbung vorzuziehen!
Keine Klassen spezialisieren, welche nicht explizit für Vererbung vorgesehen sind.
- Ohne explizite Dokumentation: Keine Spezialisierung (auch wenn nicht final)
Komposition ist deutlich flexibler und wartungsfreundlicher
- Wrapper- / Delegate- oder Decorator-Pattern (GoF)
- Komposition ist leicht austauschbar, ohne Einfluss auf Interface
Was ist mit "Design for inheritance, or prohibit it" gemeint?
Eine gut spezialisierbare (Basis-)Klasse zu schreiben ist wirklich anspruchsvoll!
Teile der Implementation müssen dafür in der API dokumentiert werden, was implizit die Datenkapselung verletzt
Wenn möglich keine überschreibbaren Methoden aufrufen, auf keinen Fall aber in Konstruktoren oder Methoden mit ähnlichem Charakter (Gefahr der pränatalen Kommunikation)
Im Zweifelsfall eine Spezialisierung besser explizit verhindern. Wie?
Klasse mit final markieren (oder private Konstruktoren)
Was bedeutet hohe Kohäsion?
Man fasst in einer Klasse Attribute und Methoden zusammen, die wirklich zusammengehören, und nicht mehr!
- Kohäsion ist optimal, wenn eine weitere Teilung unsinning ist
Was bedeutet lose Kopplung?
So viele starke Beziehungen zwischen Klassen wie nötig, so wenig und schwache Beziehungen wie möglich.
- Klassen aus den Java-Libraries kann man ignorieren
- Abhängig zu Thirdparty-Klassen jedoch besonders genau betrachten
Was unterstützen Datenkapselung und Information Hiding?
Datenkapselung und Information Hiding unterstützen hohe Kohäsion und lose Kopplung
Was sind die Grundprinzipien von Datenkapselung?
Expliziter und bewusster Umgang mit Zugriffsmodifikatoren
- Attribute möglichst immer privater
- Aber nicht einfach alle Methoden public
- Blindes generierten von Setter-/Getter-Methoden reicht nicht!
Was ist das Fundament von Information Hiding?
Schnittstelle und Implementation möglichst strickt trennen. Die Schnittstelle sollte möglichst keine Rückschlüsse auf die interne Implementation ermöglichen (echte Design-Entscheide)
Gute Datenkapselung und Information Hiding fördern was?
Fördern direkt die hohe Kohäsion und die lose Kopplung
Weshalb sollte man Schnittstellen verwenden?
Schnittstellen sind ein wunderbares Mittel zur Abstraktion und Entkopplung.
- Schnittstellen sind die bessere Alternative zu vollabstrakten Klassen.
- Desing by interfaces: Man konzentriert sich immer zuerst auf das was und erst später bei der Implementation auf das wie, setzen somit den Fokus auf die Perspektive des Nutzers einer Klasse
- Erleichtern die Umsetzung von Test-First
- Lieber zu viele Schnittstellen als zu wenig!
Weshalb sollte man mit Unit-Tests und dem Test First Prinzip arbeiten?
- Wir testen nicht, um nachträglich Fehler zu finden!
- Sondern wir testen, um fortlaufend die Gewissheit zu erhalten, dass es funktioniert!
- Automatisiertes, selbst-validierendes Testen ist extrem Effizient (JUnit als populärstes Framework, weit verbreitet und integriert
- Test First Prinzip / Test-Driven Develepment:
Vor der Implementation die Testfälle schreiben!
- Früh die Perspektive des Nutzers einer Klasse einnehmen
- Spezial- und Sonderfälle werden intuitiver aufgedeckt
- ...und bei der Implementation ebenso intuitiv berücksichtigt
- Kein Projekt und keine Klasse ist zu klein, um nicht mit Unit-Test getestet zu sein!
Weshalb sind viele kleine Einheiten besser als wenige Grosse?
- besser Wiederverwendbar und Testbar (höhere Kohäsion)
- Bei jeder Methode die man ergänzt, bei jeder Erweiterung die man macht: Immer hintefragen, ob es nicht besser wäre, eine bestehende Klasse oder Methode aufzuteilen!
Kurzfristig höherer Arbeitsaufwand zahlt sich später x-fach aus.
Refactoring ist ein dauernder Prozess
Wie wichtig ist die Namensgebung und die Formatierung des Quellcodes?
Sehr wichtig, gute Namensgebung sorgt für aussagekräftigen und leichtverständlichen Quellcode, der besser Wart- und Erweiterbar ist.
- Hilft Sinn und Absicht schneller zu Verstehen
- reduziert Aufwand für Dokumentation
- erhält Kohäsion (Verletzungen schneller erkennbar)
Halte den Quellcode sauber und formatiert!
Für was sind Datenströme (Streams) ein grundlegendes Konzept?
Für die Dateneingabe und -ausgabe
Weshalb sind wir sehr flexibel, aus welcher Art von Datenquelle und zu welcher Art von Datensenke die Daten verarbeitet werden?
Ein Java-Programm kann auf abstrakter Ebene:
- Daten aus einem beliebigen Eingabestrom lesen
- Daten in einen beliebigen Ausgabestrom schreiben
- eine Datei auf einem Dateisystem (FS- und OS-unabhängig!)
- Eingaben von einer Tastatur und Ausgabe auf eine Konsole
- Netzwerkkommunikation (Socket, TCP/IP etc.)
In welchen beiden Packages befinden sich die wesentlichen Klassen zu Datenströme?
java.io und java.nio
Zwischen welchen beiden Arten von Datenströmen unterscheidet Java?
Byte-Datenströme und Zeichen-Datenströme
Was sind die Basisklassen für alle Byte-Datenströme?
InputStream und OutputStream
Die Daten von Byte-Datenströme werden Byte-weise (Werte 0..255) behandelt, aber in Java als was dargestellt?
als int
Ende eines Streams (EOS) bzw. einer Datei (EOF) wird mit dem Wert -1 signalisiert
Welchem Datenstrom bedienen sich die vorinstanziierten Objekte System.in (Typ: InputStream) und System.out (Typ: PrintStream) für den Standard-I/O?
Sie bedienen sich der Byte-Datenströme
Das native Schreiben von einzelnen Datenwerten oder auch ganzer Objekte (-> Objekt-Serialisierung) basiert auf welchen Datenströmen?
Byte-Datenströmen
Regel: Alle IO-Klassen, welche mit Byte-Datenströmen umgehen, tragen die welche Wörter im Namen?
InputStream bzw. OutputStream
Was machen die Klassen FileInputStream und FileOutputStream?
Sie unterstützen den I/O mit Dateien
Was machen die Klassen BufferedInputStream und BufferedOutputStream?
Unterstützen gepufferte (cache) I/O-Streams
Was machen die Klassen DataInputStream und DataOutputStream?
Unterstützen den I/O mit/für elementare Datentypen
Was macht die Klasse PrintStream?
Ermöglicht die Ausgabe von ASCII-Text (nicht Unicode) direkt auf die Konsole (das ist System.out!)
Was bedeutet Kaskadierung von Stream-Objekten?
Beachte, die meisten I/O-Klassen, welche von Basisklassen InputStream bzw. OutputStream spezialisiert sind, die Typen auch wieder verwenden und als formalen Parameter des Konstruktors entgegen nehmen.
Somit lassen sich die verschiedenen Spezialisierungen zu Ketten verbinden (Kaskadierung) und die einzelnen Funktionalitäten miteinander kombinieren!
- Decorator- (bzw. Wrapper-)Pattern nach -> GoF
Wenn wir I/O-Operationen durchführen, verwenden wir implizit Ressourcen, welche nicht unter der Kontrolle von Java (sondern des OS) stehen, und welche typisch explizit geöffnet und geschlossen werden müssen. Was macht man häufig und was wäre besser um diese Ressourcen zu öffnen und schliessen?
- öffnen: Erfolgt durch Erzeugen (new) des entsprechenden Objektes in Java wieder implizit
- schliessen: Garbage Collection von Java ist dafür nicht geeignet (käme viel zu spät), wir müssen I/0-Ressourcen explizit mit close() schliessen!
Häufig: Schliessen in einem finally-Block gemacht (wird immer ausgeführt, egal was)
Besser: Java 7 hat dafür eine try-Anweisung eingeführt
Besonders beim Fehlerhandling von I/O-Operationen können unterschiedlichste Fehler auftreten, welche zwar einzeln gefangen werden, häufig aber identisch behandelt würden (Redundanzen) Was kann man dagegen machen?
Seit Java 7 kann man die Exceptiontypen durch ein pipe-Symbol | getrennt in einem catch auflisten
(siehe Bild)
Hinweis: Explizit nur für die Fälle, in welchen keine (sinnvolle) gemeinsame Basisklasse existiert!
Was sind die Basisklassen für alle Zeichen-Datenströme?
Reader und Writer
Die Zeichen-Datenströme werden als 16bit-Unicode-Charakter behandelt (Werte 0..65535), aber in Java als was dargestellt?
als int, Ende eines Streams (EOS) bzw. einer Datei (EOF) wird mit dem Wert -1 signalisiert
Mit Zeichen-Datenströmen kann was sehr einfach gehandhabt werden?
Text-Dateien (z.B. formatierter Text, XML, JSON -> von Menschen lesbare Formate).
Eine beliebig lange Kette von Zeichen, optional in Zeilen
Achtung: Zeichen-Datenströme sind encodiert, Java-intern werden alle Strings als UTF-8 encodiert
Regel: Alle IO-Klassen, welche mit Zeichen-Datenströmen arbeiten, tragen die Teilwörter _______ bzw. _________ im Namen.
Reader, Writer