Rheinwerk Computing < openbook >


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


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

Pfeil 14 Architektur, Design und angewandte Objektorientierung
Pfeil 14.1 SOLIDe Modellierung
Pfeil 14.1.1 DRY, KISS und YAGNI
Pfeil 14.1.2 SOLID
Pfeil 14.1.3 Sei nicht STUPID
Pfeil 14.2 Architektur, Design und Implementierung
Pfeil 14.3 Design-Patterns (Entwurfsmuster)
Pfeil 14.3.1 Motivation für Design-Patterns
Pfeil 14.3.2 Singleton
Pfeil 14.3.3 Fabrikmethoden
Pfeil 14.3.4 Das Beobachter-Pattern mit Listener realisieren
Pfeil 14.4 Zum Weiterlesen
 

Zum Seitenanfang

14    Architektur, Design und angewandte Objektorientierung Zur vorigen ÜberschriftZur nächsten Überschrift

»Eines der traurigsten Dinge im Leben ist, dass ein Mensch viele gute Taten tun muss, um zu beweisen, dass er tüchtig ist, aber nur einen Fehler zu begehen braucht, um zu beweisen, dass er nichts taugt.«

– George Bernard Shaw (1856–1950)

Während die Beispiele aus Kapitel 2 bis Kapitel 13 im Wesentlichen in einer kleinen main(…)-Methode Platz fanden, wollen wir in diesem Kapitel ein paar Best Practices kennenlernen, wie sich Typen entkoppeln lassen, und uns anschauen, welche Mechanismen es zur Aufteilung auf Typen gibt.

Professionelle Architektur und solide Modellierung sorgen für Belastbarkeit.

Abbildung 14.1     Professionelle Architektur und solide Modellierung sorgen für Belastbarkeit.

 

Zum Seitenanfang

14.1    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

14.1.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 (etwa aus 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

14.1.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 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.[ 231 ](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

14.1.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 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 vermeintlich 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: Algorithmen in Java

Algorithmen in Java




Zum Rheinwerk-Shop: Spring Boot 3 und Spring Framework 6

Spring Boot 3 und Spring Framework 6




Zum Rheinwerk-Shop: Java SE 9 Standard-Bibliothek

Java SE 9 Standard-Bibliothek




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

InfoInfo



 

 


Copyright © Rheinwerk Verlag GmbH 2024

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