5.1 Einführung Objektorientierung
5.1 Einführung Objektorientierung"Information Hiding" und Datenkapselung im abstrakten Datentyp
Ein Bestandteil der Objektorientierung ist das "information Hiding" welches schon von den abstrakten Datentypen her bekannt ist. Der Zustand des Objekts wird durch seine Attribute bestimmt. Die Attribute sollen aber nicht beliebig geändert werden können. Die Methoden agieren als Wächter für die Zustandsübergänge und "bewachen" so zu sagen die Attribute des Objekts. Dies hat zwei wesentliche Vorteile
- Der Entwickler kann denn Zustand seines Objekts bzw. Datentyps immer genau kontrollieren
- Der Entwickler kann die interne Implementierung des Objekts an neue Anforderungen anpassen ohne, dass er dies mit den Benutzern des Objekts kommunizieren muss. Die Methoden bilden hierdurch eine Schnittstelle zwischen der Implementierung und der externen Sicht des Objekts
Methoden erfüllen in diesem Kontext mehrere Aufgaben:
- Sie lesen die internen, geschützten Datenstrukturen aus
- Sie ändern die internen Datenstrukturen
- Sie können komplexe Berechnungen durchführen
- Sie können wiederum andere Objekte manipulieren (von denen der Benutzer nichts weiß)
Information Hiding: Ein Teilsystem darf nichts von der Implementierung eines anderen Teilsystems wissen
Klasse
Nach Wikipedia:
Unter einer Klasse versteht man in der objektorientierten Programmierung ein abstraktes Modell bzw. einen „Bauplan“ für eine Reihe von ähnlichen Objekten.
Die Klasse dient als Bauplan für Abbildung von realen „Objekten“ in Softwareobjekten und enthält Attribute (Eigenschaften) und Methoden (Verhaltensweisen) der Objekte. Verallgemeinernd könnte man auch sagen, dass eine Klasse dem Datentyp eines Objekts entspricht.
Klassen
- sind eine Menge von gleichartigen, individuellen Objekten
- sind ein schematische Modell
- beschreiben
- Eigenschaften (die Attribute einer Klasse)
- Verhalten (Methoden)
Objekt
Nach Wikipedia:
Ein Objekt bezeichnet in der objektorientierten Programmierung (OOP) ein Exemplar eines bestimmten Datentyps oder einer bestimmten Klasse (auch „Objekttyp“ genannt). In diesem Zusammenhang werden Objekte auch als „Instanzen einer Klasse“ bezeichnet. Objekte sind also konkrete Ausprägungen („Instanzen“) eines Objekttyps.
- 7016 views
5.1.1 Datenkapselung
5.1.1 DatenkapselungDas erste Konzept, die Datenkapselung, kann man als eine technische Weiterentwicklung der abstrakten Datentypen sehen.
- Primitive Datentypen (z.Bsp. int x = 10;)
- Strukturierte Datentypen wie Felder oder struct in der Programmiersprache C erlauben mehrere Typen in einer Struktur zusammenzufassen.
- Klassen, die es erlauben mehrere Datentypen (diese werden Attribute genannt) mit den dazugehörigen Methoden zusammenzufassen und zu kapseln.
- Beispiel: Eine Linie, die aus zwei Punkten besteht und den Zugriff auf die Punkte nur nach bestimmten Vorschriften in Methoden kapselt.
Datenkapselung ist das Verbergen von Attributen und Methoden durch Einschränkung des Zugriffs von Ausserhalb der Klasse.
Durch dieses Prinzip ergeben sich beim Entwurf und bei der Wartung von Anwendungen eine Reihe von Vorteilen:
- Divide et impera (Teile und herrsche): Benutzer und Implementierer einer Klasse können unabhängig von einander entwickeln. Der Entwickler muss nur darauf achten die externen Schnittstellen (öffentliche Methoden und Attribute) stabil zu halten.
- Integrität: Unbeabsichtigte Zustandsänderungen werden unterbunden. Beim Setzen eines Attributs müssen eventuell noch andere Operationen durchgeführt werden.
Datenkapselung ist die Voraussetzung zur Implementierung von Schnittstellen:
Schnittstelle |
---|
Die Gesamtheit der öffentlichen Strukturen einer Datenstruktur(Klasse) mit der Konsumenten(Verwender) einer Datenstruktur interagieren können. Schnittstellen stellen die Funktionalität einer Datenstruktur(Klasse) nach außen zur Verfügung. |
Entwickler sollten beim Anwendungsentwurf eine:
- maximale Datenkapselung und
- minimale Schnittstelle
einplanen. Klassen sollten möglichst autark sein und auf möglichst wenig andere Schnittstellen und Klassen zugreifen.
Sichtbarkeitssteuerung in Java mit Hilfe der Schlüsselwörter public und private
Java erlaubt den Zugriff auf Methoden und Attribute mit Hilfe der Schlüsselwörter private und public vor dem Namen des Attributs oder Methode zu steuern:
- public: Methoden und Attribute einer Klasse können
- von Methoden der Klasse selbst genutzt werden
- von Methoden andere Klassen genutzt werden (externe Benutzung)
- private: Methoden und Attribute einer Klasse können
- von Methoden der Klasse selbst genutzt werden
- nicht von Methoden ausserhalb der Klasse genutzt werden
Diese Zugriffssteuerung erlaubt die Implementierung der folgenden Empfehlung
|
Attribute und Methoden ohne ein Schlüsselwort werden in Java als public Attribute und Methoden behandelt um den Zugriff im gleichen Paket zu erlauben.
Java verfügt auch über das Schlüsselwort protected welches den Zugriff nur innerhalb eines Pakets erlaubt. Pakete werden erst in der weiterführenden Vorlesung eingeführt werden.
Zugriffssteuerung mit Get- und Set- Methoden
Es ist eine Konvention (und guter Programmierstil) in Java den Zugriff auf private Attribute mit Methoden zu gewähren denen man vor dem Attributnamen get- bzw. set- voranstellt:
class Person() { private String name; public void setName(String n) { name = n;} public String getName() { return name;} } |
Dieser Programmierstil bietet eine Reihe von Vorteilen:
- zukünftige Wartungsaufwände und Erweiterungen können leichter implementiert werden, da externe Benutzer ihre Implementierung nicht ändern müssen
- Die interne Implementierung kann vollständig geändert werden solange die Signatur der öffentlichen Methoden unverändert bleibt.
- get-, set- Methoden erlauben das Implementieren weitergehender Konsistenzprüfungen.
Anmerkung: Laufzeiteinbußen durch solche Trivialmethoden sind in der Regel nicht zu befürchten. Der Java "Just in Time" (JIT) Übersetzer des Laufzeitsystems wird mit hoher Wahrscheinlichkeit solche Methoden zur Laufzeit durch Methoden-inlining wegoptimieren.
- 9900 views
5.1.2 Architekturprinzipien
5.1.2 ArchitekturprinzipienTrennung der Zuständigkeiten
Trennung von Zuständigkeiten(Separation of Concerns) ist ein Konzept welches auf Datenkapselung aufbaut.
Die Idee besteht darin Zuständigkeiten Klassen zu zuordnen.
Alle Aufgaben die in einen Bereich fallen sollen möglichst von genau einer Klasse implementiert werden. Ziel ist es, dass unabhängige Dinge auch in der Implementierung unabhängig voneinander bleiben. Hierdurch
- sinkt die Gesamtkomplexität und Systeme sind einfacher zu verstehen
- unterschiedliche Komponenten können unabhängig von einander gepflegt werden
- Fehler in einem Bereich sollen sich möglichst nicht in einem anderen Bereich bemerkbar machen
Ziel ist es Klassen so zu modellieren, dass sie möglichst in sich abgeschlossen sind.
Ein Beispiel hierfür:
- Die Webarchitektur
- html (Hypertext Markup Language) ist die Seitenbeschreibungssprache
- css (Cascading Style Sheets) ist die Sprache zur Beschreibung des Layouts der Seite (getrennt vom Inhalt)
- http ist das Protokoll zur Übertragung der html Seiten (getrennt vom Inhalt)
- html (Hypertext Markup Language) ist die Seitenbeschreibungssprache
Entwurfsmuster "Model View Controller" (MVC)
MVC ist ein Entwurfmuster welches aus den folgenden drei Einheiten besteht:
|
Die Einteilung einer Anwendung in die folgenden drei Bereich ist oft vorteilhaft da häufig
- die Benutzerschnittstellen angepasst oder ausgetauscht werden müssen. Das Datenmodell ist dann nicht betroffen. Die Benutzerschnittstelle sollte unabhängig von den anderen Komponenten sein um unterschiedliche Technologien (Web, rich client, OS spezifische Bibliotheken) nutzen zu können
- das Datenmodell auf andere Datenbankprodukte angepasst werden muss ohne das andere Komponenten davon betroffen sein sollen
- die Ablauflogik angepasst werden muss und die Änderungen in den Benutzerschnittstellen minimal gehalten werden sollen
Wichtig ist zu verstehen, dass die drei Komponenten zusammenarbeiten und idealerweise unabhängig voneinander sind. Das Model sollte zum Beispiel auf Aufrufe von View und Controller reagieren, jedoch nicht selbst diese Komponenten aufrufen.
Schichtenarchitektur
Schichtenarchitekuren sind eine andere Ausprägug der "Separation of Concerns".
Java selbst und Javaanwendungen basieren auf dem Schichtenmodell.
Eine Javaanwendung soll nur auf die Dienste der Java Runtime zurückgreifen. Die Java Runtime bietet hierfür eine reichhaltige Infrastruktur für GUI Programmierung, Datenbankzugriff, Netzwerkkommunikation, Dateizugriff etc. Beschränkt man sich auf die von der Java Runtime angebotenen Dienste wird man unabhängig vom Betriebssystem und der darunter liegenden Hardware. Ziel bei der Entwicklung einer Anwendung sollte es sein unterschiedliche Schichten zu identifizieren und von Klassen nur auf die eigene Schicht oder die darunter liegende Schicht zu beschränken. |
- 7183 views
5.1.3 Entwurfsmuster (Design Patterns)
5.1.3 Entwurfsmuster (Design Patterns)
Nach Wikipedia:
|
Referenzen
Im zweiten Semester werden die Entwurfsmuster
benutzt.
In der Vorlesung des ersten Semesters werden einige wenige, ausgewählte Entwurfsmuster vorgestellt:
- 5901 views
Factory (Fabrikmethode)
Factory (Fabrikmethode)Es gibt Situation, in denen möchte man die Erzeugung neuer Objekte nicht im Konstruktor einer Klasse durchführen weil man z.Bsp.
- Zusätzliche Verwaltungsaufgaben durchführen möchte (z.Bsp. Registrierung des Objekts)
- Nicht mehr benötigte Objekte wieder verwenden möchte ( z.Bsp. Datenbankverbindungen)
- Die Wahl haben möchte Unterschiedliche Spezialisierungen einer Klasse oder die Implementierung einer Schnittstelle nutzen möchte.
Dieser Anwendungsfall wird mit dem Entwurfsmuster "Factory" (Fabrikmethode) beschrieben.
VerwendungEine Fabrikmethode
Eine Fabrikmethode (Factory) besteht typischer Weise aus
KategorieEine Fabrikmethode (Factory) gehört zur Kategorie der Erzeugungsmuster (Creational Pattern). |
UML Diagramm
|
Naive Javaimplementierung
/** * Einfache Implementierung der Fabrikmethode (Factory) */ public class Factory { /** * privater Konstruktor der nur innerhalb der Klasse * aufgerufen werden kann */ private Factory() { // Individuelle Initialisierung erfolgt hier } /** * Erzeugen der Objekte. */ public static Factory getInstance() { // Vorarbeiten instanz = new Factory(); // Nacharbeiten return instanz; }}
- 2022 views
Singleton (Einzelstück)
Singleton (Einzelstück)Es gibt Anwendungsfälle in denen es gewünscht ist genau ein Objekt global zur Verfügung zu stellen. Dieser Anwendungsfall wird mit dem Entwurfsmuster "Singleton" (Einzelstück) beschrieben. Beispiele für solche Anwendungsfälle sind:
- Implementierung eines seriellen logging Mechanismus
- Implementierung eines Puffers für einen Drucker
VerwendungEin Einzelstück
Ein Singleton (Einzelstück) implementiert eine ähnliche Struktur wie eine globale Variable. KategorieDas Einzelstück (Singleton) gehört zur Kategorie der Erzeugungsmuster (Creational Pattern). |
UML Diagramm
|
Naive Javaimplementierung (Lazy initialization)
/** * Einfache Implementierung des Einzelstueck (Singleton */ public class Einzelstueck { private static final Einzelstueck instanz; /** * privater Konstruktor der nur innerhalb der Klasse * aufgerufen werden kann */ private Einzelstueck() { // Individuelle Initialisierung erfolgt hier } /** * Erzeugen des einzigen Objekts falls noch keines existiert. * Rückgabe des Objekts falls es schon existiert * Diese Methode ist statisch. Sie kann auch ohne die Existenz einer Instanz aufgerufen werden. * Die Methode ist die einzige öffentliche Methode */ public static Einzelstueck getInstance() { if (instanz == null) { instanz = new Einzelstueck(); } return instanz; }}
Das gezeigte Beispiel verwendet eine "Lazy initialization". Das Objekt wird erst erzeugt wenn es auch wirklich benötigt wird. Hierdurch kann das unnötige Allokieren von Ressourcen vermieden werden.
Der Nachteil dieser Implementierung besteht darin, dass sie nicht threadsicher ist. In einem Javaprogramm mit mehreren Threads (Ausführungseinheiten) können zwei Threads gleichzeitig ein Objekt erzeugen und damit das gewünschte Ziel des Einzelstücks durchkreuzen.
Threadsichere Javaimplementierung
/** * Threadsichere Implementierung des Entwurfsmuster Einzelstueck (Singleton) */ public class Einzelstueck { private static Einzelstueck instanz = new Einzelstueck(); /** * privater Konstruktor der nur innerhalb der Klasse * aufgerufen werden kann */ private Einzelstueck() { // Individuelle Initialisierung erfolgt hier } /** * Diese Methode ist statisch. Sie kann auch ohne die Existenz einer Instanz aufgerufen werden. * Die Methode ist die einzige öffentliche Methode */ public static Einzelstueck getInstance() { return instanz; } }
Die hier gezeigte Implementierung ist threadsicher da die Instanz schon beim Laden der Klasse erzeugt wird.
- 7262 views