Rheinwerk Computing < openbook >


 
Inhaltsverzeichnis
Materialien
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Arrays und ihre Anwendungen
5 Der Umgang mit Zeichenketten
6 Eigene Klassen schreiben
7 Objektorientierte Beziehungsfragen
8 Ausnahmen müssen sein
9 Geschachtelte Typen
10 Besondere Typen der Java SE
11 Generics<T>
12 Lambda-Ausdrücke und funktionale Programmierung
13 Architektur, Design und angewandte Objektorientierung
14 Java Platform Module System
15 Die Klassenbibliothek
16 Einführung in die nebenläufige Programmierung
17 Einführung in Datenstrukturen und Algorithmen
18 Einführung in grafische Oberflächen
19 Einführung in Dateien und Datenströme
20 Einführung ins Datenbankmanagement mit JDBC
21 Bits und Bytes, Mathematisches und Geld
22 Testen mit JUnit
23 Die Werkzeuge des JDK
A Java SE-Module und Paketübersicht
Stichwortverzeichnis


Download:

- Listings, ca. 2,7 MB


Buch bestellen
Ihre Meinung?



Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenboom

Einführung, Ausbildung, Praxis
Buch: Java ist auch eine Insel


Java ist auch eine Insel

Pfeil7 Objektorientierte Beziehungsfragen
Pfeil7.1 Assoziationen zwischen Objekten
Pfeil7.1.1 Unidirektionale 1:1-Beziehung
Pfeil7.1.2 Zwei Freunde müsst ihr werden – bidirektionale 1:1-Beziehungen
Pfeil7.1.3 Unidirektionale 1:n-Beziehung
Pfeil7.2 Vererbung
Pfeil7.2.1 Vererbung in Java
Pfeil7.2.2 Spielobjekte modellieren
Pfeil7.2.3 Die implizite Basisklasse java.lang.Object
Pfeil7.2.4 Einfach- und Mehrfachvererbung *
Pfeil7.2.5 Sehen Kinder alles? Die Sichtbarkeit protected
Pfeil7.2.6 Konstruktoren in der Vererbung und super(…)
Pfeil7.3 Typen in Hierarchien
Pfeil7.3.1 Automatische und explizite Typumwandlung
Pfeil7.3.2 Das Substitutionsprinzip
Pfeil7.3.3 Typen mit dem instanceof-Operator testen
Pfeil7.4 Methoden überschreiben
Pfeil7.4.1 Methoden in Unterklassen mit neuem Verhalten ausstatten
Pfeil7.4.2 Mit super an die Eltern
Pfeil7.4.3 Finale Klassen und finale Methoden
Pfeil7.4.4 Kovariante Rückgabetypen
Pfeil7.4.5 Array-Typen und Kovarianz *
Pfeil7.5 Drum prüfe, wer sich dynamisch bindet
Pfeil7.5.1 Gebunden an toString()
Pfeil7.5.2 Implementierung von System.out.println(Object)
Pfeil7.5.3 Nicht dynamisch gebunden bei privaten, statischen und finalen Methoden
Pfeil7.5.4 Dynamisch gebunden auch bei Konstruktoraufrufen *
Pfeil7.5.5 Eine letzte Spielerei mit Javas dynamischer Bindung und überdeckten Attributen *
Pfeil7.6 Abstrakte Klassen und abstrakte Methoden
Pfeil7.6.1 Abstrakte Klassen
Pfeil7.6.2 Abstrakte Methoden
Pfeil7.7 Schnittstellen
Pfeil7.7.1 Schnittstellen sind neue Typen
Pfeil7.7.2 Schnittstellen deklarieren
Pfeil7.7.3 Abstrakte Methoden in Schnittstellen
Pfeil7.7.4 Implementieren von Schnittstellen
Pfeil7.7.5 Ein Polymorphie-Beispiel mit Schnittstellen
Pfeil7.7.6 Die Mehrfachvererbung bei Schnittstellen
Pfeil7.7.7 Keine Kollisionsgefahr bei Mehrfachvererbung *
Pfeil7.7.8 Erweitern von Interfaces – Subinterfaces
Pfeil7.7.9 Konstantendeklarationen bei Schnittstellen
Pfeil7.7.10 Nachträgliches Implementieren von Schnittstellen *
Pfeil7.7.11 Statische ausprogrammierte Methoden in Schnittstellen
Pfeil7.7.12 Erweitern und Ändern von Schnittstellen
Pfeil7.7.13 Default-Methoden
Pfeil7.7.14 Erweiterte Schnittstellen deklarieren und nutzen
Pfeil7.7.15 Öffentliche und private Schnittstellenmethoden
Pfeil7.7.16 Erweiterte Schnittstellen, Mehrfachvererbung und Mehrdeutigkeiten *
Pfeil7.7.17 Bausteine bilden mit Default-Methoden *
Pfeil7.7.18 Initialisierung von Schnittstellenkonstanten *
Pfeil7.7.19 Markierungsschnittstellen *
Pfeil7.7.20 (Abstrakte) Klassen und Schnittstellen im Vergleich
Pfeil7.8 SOLIDe Modellierung
Pfeil7.8.1 DRY, KISS und YAGNI
Pfeil7.8.2 SOLID
Pfeil7.8.3 Sei nicht STUPID
Pfeil7.9 Zum Weiterlesen
 

Zum Seitenanfang

7.8    SOLIDe Modellierung Zur vorigen ÜberschriftZur nächsten Überschrift

Wer gute objektorientierte Software schreiben möchte, sollte sich an einige Designprinzipien halten. Es sind Best-Practice-Methoden, die natürlich nicht zwingend sind, aber in der Regel das Design verbessern.

 

Zum Seitenanfang

7.8.1    DRY, KISS und YAGNI Zur vorigen ÜberschriftZur nächsten Überschrift

Die ersten drei Regeln sind:

  • DRY (Don’t Repeat Yourself): »Wiederhole dich nicht.« Codeduplizierung sollte vermieden und doppelter Code in Methoden ausgelagert werden. Das heißt auch, dass bestehender Code (aus etwa eigenen Bibliotheken, der Java SE oder quelloffenen Bibliotheken) verwendet werden soll.

  • KISS (Keep It Simple, Stupid): »Halte es einfach und idiotensicher«. Ein Problem soll einfach und leicht verständlich gelöst werden. Für Entwickler bedeutet dies: einfacher Code, wenige Zeilen Code, auf den ersten Blick verständlich.

  • YAGNI (You Ain’t Gonna Need It): Das Prinzip »Du wirst es nicht brauchen« soll uns daran erinnern, einfachen Code zu schreiben und nur das zu programmieren, was im Moment in der Anforderung auch erwartet wird. YAGNI ist ein zentraler Punkt im Extreme Programming (XP) und der Idee »Implementiere immer die einfachste mögliche Lösung, die funktioniert«, denn wenn etwas programmiert wird, was später nie produktiv wird, ist es Zeit- und Geldverschwendung, aber der Code muss dennoch dokumentiert, gewartet und getestet werden.

 

Zum Seitenanfang

7.8.2    SOLID Zur vorigen ÜberschriftZur nächsten Überschrift

Michael Feathers hat die Abkürzung SOLID eingeführt und fünf Punkte benannt, die einen guten objektorientierten Entwurf ausmachen. Die einzelnen Kriterien selbst stammen von unterschiedlichen Autoren.

S: Single Responsibility Principle (SRP)

Etwas flapsig ausgedrückt steht das Prinzip für: »Mache genau eine Sache, die aber richtig.« Ein Typ sollte genau eine Verantwortung (engl. responsibility) haben, sodass bei Änderungen im besten Fall auch nur eine Stelle angepasst werden muss und nicht viele Stellen. Das Gegenteil sind sogenannte Gott-Klassen, die alles können – ein Anti-Pattern. Robert Martin, der das SRP in seinem Buch »Agile Software Development: Principles, Patterns, and Practices« beschreibt, sagt auch: »Es sollte nie mehr als einen Grund geben, eine Klasse zu ändern.« Was heißt das nun praktisch?

Nehmen wir an, eine Person-Klasse speichert Namen, PLZ und Alter. An PLZ und Alter gibt es Anforderungen: Eine deutsche PLZ besteht nur aus Ziffern, ist 5 Stellen lang, und ein Alter ist sicherlich nicht negativ und nach oben beschränkt. Allerdings sind diese beiden Validierungen zwei unterschiedliche Dinge, also übernimmt die Person-Klasse Verantwortlichkeiten, die an sich mit einer Person nichts zu tun haben. Demnach gibt es zwei Gründe, warum die Klasse bei einer Änderung der Validierung angepasst werden muss; und zwei Gründe sind mehr als ein Grund und folglich ein Bruch des SRP.

Treibt die Modellierung das SRP ins Extrem, entstehen sehr viele kleine Typen. Damit ist auch dem Codeversteher nicht geholfen, wenn Verantwortlichkeiten wegen Unübersichtlichkeit nicht mehr zu verstehen sind.

O: Open/closed principle

Bertrand Meyer formuliert 1988 in seinem Buch »Object-Oriented Software Construction«, dass Module sowohl offen (für Erweiterungen) als auch verschlossen (für Modifikationen) sein müssen. Unter dem Begriff Modul müssen sich Java-Entwickler einen Typ vorstellen. Eine herkömmliche Klasse ist insbesondere mit privaten Zuständen geschlossen für Modifikationen, aber eine Unterklasse erlaubt ohne Codeänderungen der Oberklasse die Erweiterung um neue Zustände oder durch das Überschreiben von Methoden eine Anpassung einer Implementierung. Eine Unterklasse darf Methoden allerdings keine andere Semantik geben, sonst würde das die Geschlossenheit brechen.

L: Liskov Substitution Principle (LSP)

Barbara Liskov hielt 1987 den Vortrag »Data abstraction and hierarchy«, in dem es um die Tatsache ging, dass es möglich sein sollte, Objekte in Programmen durch Objekte eines Untertyps zu ersetzen, ohne dass die Korrektheit leidet. Damit der Austausch funktioniert, muss natürlich der Untertyp wissen, was »korrekt« ist, damit Methoden nicht eine falsche Implementierung realisieren, die das Verhalten brechen. Flapsig ausgedrückt: Kinder müssen das Verhalten der Eltern erben und respektieren. In Java ist das nicht einfach, denn syntaktische Konstrukte wie Preconditions, Postconditions und Invarianten gibt es nicht; Java-Entwickler müssen also rein aus dem Javadoc, der textuellen Information also, herausziehen, was ein korrektes Verhalten ist.

I: Interface Segregation Principle (ISP)

Das ISP wird Robert Cecil Martin zugeschrieben, als er für Xerox am Druckersystem arbeitete. Die zentrale Aussage ist: »Viele Client-spezifische Schnittstellen sind besser als eine allgemeine Schnittstelle.« Der Client ist der Nutzer eines Java-Typs, und mit Schnittstelle ist verallgemeinert das Angebot an Methoden gemeint. Praktisch heißt das Folgendes: Es gibt Typen, die sehr viele Methoden haben und dann ein »allgemeiner« Typ wären. Werden solche Objekte herumgereicht, dann bekommen die Programmstellen immer das gesamte Objekt mit allen Methoden. Das komplette Angebot an Methoden ist aber nicht immer nötig und vielleicht sogar gefährlich. Besser ist es, die API klein zu halten und damit nur den verschiedenen Stellen das zu ermöglichen, was auch benötigt wird.

D: Dependency Inversion Principle (DIP)

»Hänge nur von Abstraktionen ab, nicht von Spezialisierungen.« So hat es Robert Cecil Martin formuliert, ursprünglich etwas länger.[ 178 ](Die erste Fassung lautet: »A. High-level modules should not depend on low-level modules. Both should depend on abstractions. B. Abstractions should not depend on details. Details should depend on abstractions.« ) Gut zu erkennen ist das Prinzip in der Schichtenarchitektur: Eine obere Schicht greift auf Dienste einer tieferen Schicht zurück. Die obere Schicht sollte sich aber nicht an konkrete Typen klammern, sondern nur von Basistypen wie Java-Schnittstellen abhängen. In diesem Zusammenhang passt gut das Prinzip Programmieren gegen Schnittstellen.

Das große Ganze

Wie in einem Quentin-Tarantino-Film hängt alles irgendwie in einem großen Designuniversum zusammen. Jedoch haben die Entwurfspraktiken Schwerpunkte: Das SRP nimmt sich Typen vor und die Architektur im Großen. Das Open-Closed-Prinzip handelt von Typen und ihren Erweiterungen. LSP handelt von Vererbung und Untertypen. Und das ISP handelt von Geschäftslogik und Abhängigkeiten der Typen.

 

Zum Seitenanfang

7.8.3    Sei nicht STUPID Zur vorigen ÜberschriftZur nächsten Überschrift

Jedem »tue« in SOLID steht ein »lass es« in STUPID gegenüber. Das Akronym steht für die die dunkle Seite:

  • Singleton: Ein Singleton ist ein Objekt, das es im System nur einmal geben kann. Solche Objekte gibt es immer wieder, und sie sind an sich nichts Schlimmes. Problematisch ist jedoch, dass viele Entwickler das Singleton selbst als Klasse schreiben, und dann entsteht schnell eine Implementierung, die sich durch den globalen Zustand schlecht testen lässt. Besser ist es, Frameworks zu nutzen, die für uns dann ein Exemplar bereitstellen.

  • Tight Coupling (enge Kopplung): Das Ziel guten Entwurfs ist die Reduktion von Abhängigkeiten; auf je weniger Module/Pakete/Typen ein Stück Code zurückgreift, desto besser. Konkret: Je weniger import-Deklarationen es gibt, umso besser.

  • Untestability (Nicht-Testbarkeit): Wird erst nach dem Design und der Programmierung über das Testen nachgedacht, ist es oft schon zu spät – schnell entsteht schwer zu testender Code, besonders wenn die Kopplung zu eng ist. Besser ist der Ansatz der testgetriebenen Entwicklung, bei der die Testbarkeit das Design beeinflusst. Am besten überlegen sich Designer und Entwickler im Vorfeld, wie eine bestimmte Klasse und Funktionalität getestet werden kann, bevor es an die intensive Implementierung geht.

  • Premature Optimization (voreilige Optimierung): Entwickler meinen, ein Gefühl dafür zu haben, welche Programmteile Performance verschlingen und welche Teile schnell sind. Oft irren sie sich, verschenken aber viel Zeit bei der Optimierung dieser vermeindlich langsamen Stellen. Der beste Ansatz ist, nach KISS eine einfache Lösung zu realisieren und dann über einen Profiler sich genau die Stellen aufzeigen zu lassen, die Nacharbeit erfordern.

  • Indescriptive Naming (nichtbeschreibende Benennung): Variablennamen wie one, z, l, myvariable, var1, val10, theInt, aDouble, _1bool, button123 sind wenig sprechend und müssen vermieden werden. Der Programmleser sollte sofort wissen, worum es sich bei der Variablen handelt.

  • Duplikationen: Code, der mit kleinen Änderungen 1:1 kopiert wurde, ist zu vermeiden. Codeduplikate lassen sich mit Werkzeugen und IDE-Plugins relativ gut finden.

 


Ihre Meinung?

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Java ist auch eine Insel Java ist auch eine Insel

Jetzt Buch bestellen


 Buchempfehlungen
Zum Rheinwerk-Shop: Captain CiaoCiao erobert Java

Captain CiaoCiao erobert Java




Zum Rheinwerk-Shop: Java SE 9 Standard-Bibliothek

Java SE 9 Standard-Bibliothek




Zum Rheinwerk-Shop: Algorithmen in Java

Algorithmen in Java




Zum Rheinwerk-Shop: Objektorientierte Programmierung

Objektorientierte Programmierung




 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und in die Schweiz

InfoInfo



 

 


Copyright © Rheinwerk Verlag GmbH 2021

Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.

Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 

[Rheinwerk Computing]



Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de



Cookie-Einstellungen ändern