Drei objektorientierte Designprinzipien, die du unbedingt verwenden solltest!

Keylearnings:

  • Was ist das Hollywood Prinzip?
  • Was bedeutet Dependency Inversion?
  • Was versteht man unter dem Prinzip des Least Knowledge?
  • Was ist Demeters Law?

Wir haben uns bereits hier darüber unterhalten warum uns die Beachtung gewisser Regeln vor einem Satz blauer Augen bewahren kann.

Zum einen arbeiten wir insbesondere bei größeren Projekten nicht alleine und auch unsere Kollegen müssen mit unserem Code ohne Nervenzusammenbruch arbeiten und ihn wiederverwenden können.

Aber natürlich haben wir auch selber etwas davon.

Omas Apfelkuchen ist der Beste!

Also warum das Rezept ändern, wenn wir ein Problem auf bewährte und vor allem bekannte Weise lösen können.

Daher  wollen wir uns in diesem Artikel mit drei weiteren objektorientierten Designprinzipien beschäftigen.

Das Hollywood Prinzip

Don’t call us we call you!

Oder auf deutsch: Wir melden uns bei Ihnen!

Das ist die Art wie Agenten in Hollywood ihre Casting Kandidaten verabschieden.

Sobald sich ein Kandidat als geeignet erweist, wird dieser hierüber vom Agenten informiert. Umgekehrt ist der Agent aber nicht vom Kandidaten zu erreichen.

Ein objektorientiertes Konzept, das genau nach diesem Prinzip funktioniert sind die Events.

Wie funktionieren Events beispielsweise innerhalb einer Textverarbeitung?

Im groben besteht eine Textverarbeitung, wie beispielsweise Word, aus zwei Bereichen.

Zum einen den Bereich, in welchem du dein Textdokument bearbeitest und zum anderen ein Menü, in dem du beispielsweise die Schriftart, Schriftgröße oder Textfarbe festlegen kannst.

Wer ist hier der Agent und wer ist der Kandidat?

Anstatt von Kandidat und Agent sprechen wir in der Programmierung von Subscriber und Observer.

Sicherlich wäre es nicht besonders effektiv, wenn der Dokumentenbereich permanent beim Formatierungs-Menü nachfragt, ob der Anwender die Textformatierung angepasst hat.

Deshalb wird sobald der Anwender über das Menü den Text umformatiert ein Event ausgelöst, über das der Dokumentenbereich informiert wird und anschließend entsprechend darauf reagiert.

Hollywood_Principle

Daher übernimmt in diesem Beispiel das Formatierungs-Menü die Rolle des Observers (Agenten) und der Dokumentenbereich ist der Subscriber, der auf Benachrichtigungen durch das Menü wartet.

Besondere Bedeutung erhält das Hollywood-Prinzip im Zusammenhang mit sogenannten Frameworks.

Frameworks sind Programmbibliotheken, die dem Entwickler gewisse Standardaufgaben abnehmen.

So gibt es beispielsweise Frameworks wie Java FX, das für uns die Interaktion mit dem Anwender auf einer grafischen Benutzeroberfläche übernimmt.

Klickt der Anwender beispielsweise auf eine Schaltfläche, werden wir über  das Framework über diese Aktion informiert und können entsprechend darauf reagieren.

Das Prinzip der Dependency Inversion

Das nächste Prinzip, das wir betrachten wollen, ist das Prinzip der Dependency Inversion.

Dieses Prinzip stellt die Abstraktion und die unabhängige Implementierung in den Vordergrund.

Wir beschäftigen uns nicht mit dem Strom sondern nur mit dem Stecker und der Steckdose.

Um dieses Prinzip realisieren zu können verwenden wir das sogenannte Proxy Pattern, welches die Verwendung einer Methode unabhängig von deren konkreten Implementierung ermöglicht.

Das Werkzeug, welches wir hierfür verwenden sind die Java Interfaces.

Datenbank CRUD Operationen

Ein berühmtes Beispiel für das Prinzip der Dependency Inversion ist die Anbindung an eine Datenbank über die JPA (Java Persistence Architecture).

Die JPA dient als Schnittstelle zum verwendeten Datenbanksystem.

In jeder Datenbank benötigen wir sogenannte CRUD Operationen Create, Read, Update und Delete mit denen wir Datenbank-Einträge erstellen, lesen, modifizieren und löschen können.

Die Realisierung dieser Operationen unterscheidet sich allerdings zwischen den verschiedenen Datenbanksystemen.

So ist beispielswiese die Implementierung dieser Operationen auf einer Oracle Datenbank anders als wie in einer MySql Datenbank.

Ohne JPA müssten wir für jedes Datenbanksystem eine eigene CRUD Implementierung schreiben.

Wir hätten dann beispielsweise für jedes Datenbanksystem eine eigene speichern Methode wie saveSQL, savePostgresSQL oder saveOracle.

Und der Entwickler, der die speichern Operation verwenden möchte, müsste jedes mal prüfen, welches Datenbanksystem zugrunde liegt und in Abhängigkeit hiervon die richtige CRUD Methode aufrufen.

Sollte dann noch jemand auf die Idee kommen das Datenbanksystem zu wechseln, sind entsprechende Code Anpassungen notwendig.

Dank der JPA Schnittstelle bleibt uns das allerdings erspart. In Abhängigkeit von dem verwendeten Datenbanksystem können wir dynamisch (sogar während der Programmlaufzeit) die passende Implementierung an den JPA Proxy andocken.

Der Entwickler, der die CRUD Operation benutzen möchte kann dann unabhängig von der zugrunde liegenden Implementierung die Schnittstellen CRUD Methoden, wie z.B save, aufrufen.

Dependency Inversion

Hierbei sind die unterschiedlichen Implementierungen selbst voneinander unabhängig.

Das Prinzip des Least Knowledge!

Wir haben schon oft darüber gesprochen. Programmierer sind faul und suchen immer nach Wegen sich Arbeit zu ersparen.

Ein gute Möglichkeit das zu erreichen, ist es die getane Arbeit anderer Entwickler zu verwenden.

Das bringt allerdings nur dann etwas, wenn die Einarbeitungszeit in den fremden Programmcode so gering wie möglich ist.

Und an dieser Stelle kommt das sogenannten Prinzip des Least Knowledge, oder auf deutsch das Prinzip des Wenig-wissenden zum tragen.

Dieses Prinzip erhält besondere Wichtigkeit im Zusammenhang mit API (Application Programming Interface) Design.

Bestimmt kennst du das auch? Wenn du eine Frage hast. An wen wendest du dich? An einen guten Bekannten oder an den Fremden aus der Fußgängerzone?

Vermutlich ziehst du es vor dich an deinen Bekannten zu wenden. Oder?

Und genau das ist die Grundlage, auf dem das Prinzip des Least Knowledge beruht, das auch unter dem Namen Demeter’s Law bekannt ist.

Das Demeter’s Law empfiehlt uns, als erstes einen Freund zu Fragen und uns erst dann an einen Fremden zu wenden, wenn unser Kumpel uns nicht weiterhelfen kann.

Demeters Law

Wer ist Freund und wer ist ein Fremder?

Sicher hast du noch nie mit einer Methode, Klasse oder einem Attribut ein Bier getrunken. Oder? Also wie definieren wir in unseren Programmen, wer Freund und wer ein Fremder ist?.

Da Demiter’s Law ein objektorientiertes Design-Prinzip ist, müssen wir festlegen welche Methoden und Attribute eines Objektes zu unseren Freunden gehören.

Sinnvollerweise sind alle Methoden innerhalb der selben Klasse miteinander befreundet. Das gegenseitige Aufrufen von Methoden innerhalb der selben Klasse ist im Demiter’s Law also erlaubt.

Wer gehört noch zu unseren Freunden?

Genauso bezeichnen wir alle Objekte, die wir beim Aufrufen einer Methode als Parameter übergeben als unsere Freunde.

Des Weiteren zählen alle Objekte (und deren Attribute), die wir innerhalb der gleichen Klasse erzeugen ebenfalls zu unserem Freundeskreis.

Ein Indikator dafür, dass du gegen Demiter’s Law verstößt, ist wenn deine Methodenaufrufe mehr als einen (.) Operator haben.

Okay, üben wir das gelernte anhand eines Beispiels.

Wir sind in einer Bibliothek.

Eine Bibliothek besteht aus Bücherregalen.

Um dies in Java objektorientiert abzubilden benötigen wir also zwei Klassen. Eine Klasse für die Regale und eine Klasse für die eigentliche Bibliothek.

Die Bücherregale gehören offenbar in die Bibliothek. Daher sind die Regale mit der Bibliothek befreundet.

Jedes  Bücherregal enthält als Attribut die Anzahl der darin enthaltenen Bücher.

Das Attribut Bücheranzahl ist also ein Freund der Klasse Bücherregal nicht jedoch der Klasse Bibliothek.

Denn nehmen wir an, wir möchten die Anzahl der Bücher im zehnten Regal der Bibliothek abfragen. Wie könnte ein entsprechender Methodenaufruf aussehen?

bibliothek.getRegal(10).getAnzahlBuecher()

In unserem Aufruf befinden sich zwei Punkte. Offensichtlich verstoßen wir hier also gegen Demeters Law. Und in der Tat ist das Attribut „Anzahl Bücher“ kein Freund von der Klasse Bibliothek.

Wie können wir den Aufruf konform zum Demeters Law zu machen?

Um dieses Problem zu umgehen müssen wir der Klasse Bibliothek eine Methode hinzufügen, welche uns die Anzahl der Bücher in einem Regal direkt zurück gibt.

Eine solche Methode könnte beispielsweise wie folgt aussehen.

public int getAnzahlInRegal(int regalNummer){
	return regale[regalNummer].getAnzahlBuecher();
}

Da die Regale sich in der Bibliothek befinden, handelt es sich bei dem Attribut regale um einen Freund der Klasse Bibliothek. Innerhalb der Methode getAnzahlRegal ist das Demeters Law also nicht verletzt.

Jetzt erhalten wir die Anzahl der Bücher im Regal 10 mit folgendem Methodenaufruf.

bibliothek.getAnzahlInRegal(10)

Da die Methode getAnzahlInRegal ein Freund der Klasse Bibliothek ist, haben wir das Demeters Law in diesem Fall nicht verletzt.

Fazit: In diesem Artikel hast du drei weitere objektorientierte Designprinzipien kennengelernt. Das Hollywood Prinzip ist die Grundlage für sogenannte Frameworks, die uns in der Praxis viele, sich wiederholende und oft langweilige Routineaufgaben abnehmen.

Die Dependency Inversion ermöglicht es uns mit API’s (Application Programming Interfaces) zu arbeiten, in dem es Definition und Implementierung einer Funktion trennt.

Kern anliegen sämtlicher Designprinzipien, aber insbesondere beim Prinzip des Least Knowledge, ist es deinen Code leichter wieder-verwendbar, verständlicher und wartungsfreundlicher zu machen.

Hat dir der Artikel gefallen? Dann folge uns doch gleich auf Facebook!

Hallo ich bin Kim und ich möchte ein großer Programmierer werden. Machst du mit?

Kommentare (4)

  • Antworte

    Hey Kim,
    bei den „Key learnings“ hat sich im Word „Inversion“ ein ‚b‘ eingeschlichen.

    • Hallo Mino, danke habe es korrigiert. Viele Grüße Kim

  • Antworte

    cool !

    • Vielen Dank!

Antworte auf Aron Abbruch