Alles, was Sie über solide Prinzipien in Java wissen müssen



In diesem Artikel erfahren Sie anhand von Beispielen und deren Bedeutung anhand von Beispielen aus der Praxis ausführlich, was Solid-Prinzipien in Java sind.

In der Welt von (OOP) gibt es viele Gestaltungsrichtlinien, Muster oder Prinzipien. Fünf dieser Prinzipien sind normalerweise zusammengefasst und unter dem Akronym SOLID bekannt. Während jedes dieser fünf Prinzipien etwas Bestimmtes beschreibt, überschneiden sie sich auch so, dass die Annahme eines von ihnen die Annahme eines anderen impliziert oder dazu führt. In diesem Artikel werden wir die SOLID-Prinzipien in Java verstehen.

Geschichte der SOLID-Prinzipien in Java

Robert C. Martin gab fünf objektorientierte Gestaltungsprinzipien an, für die das Akronym „S.O.L.I.D“ verwendet wird. Wenn Sie alle Prinzipien von S.O.L.I.D kombiniert anwenden, wird es für Sie einfacher, Software zu entwickeln, die einfach verwaltet werden kann. Die anderen Merkmale der Verwendung von S.O.L.I.D sind:





  • Es vermeidet Code-Gerüche.
  • Refraktor-Code schnell.
  • Kann adaptive oder agile Softwareentwicklung durchführen.

Wenn Sie das Prinzip von S.O.L.I.D in Ihrer Codierung verwenden, beginnen Sie mit dem Schreiben des Codes, der sowohl effizient als auch effektiv ist.



Was bedeutet S.O.L.I.D?

Solid repräsentiert fünf Prinzipien von Java:

  • S. : Prinzip der Einzelverantwortung
  • ODER : Open-Closed-Prinzip
  • L. : Liskov-Substitutionsprinzip
  • ich : Prinzip der Schnittstellentrennung
  • D. : Prinzip der Abhängigkeitsinversion

In diesem Blog werden wir alle fünf SOLID-Prinzipien von Java im Detail diskutieren.



Prinzip der Einzelverantwortung in Java

Was sagt es?

Robert C. Martin beschreibt es als eine Klasse, die nur eine einzige Verantwortung haben sollte.

Nach dem Prinzip der Einzelverantwortung sollte es nur einen Grund geben, aus dem eine Klasse geändert werden muss. Dies bedeutet, dass eine Klasse eine Aufgabe zu erledigen hat. Dieses Prinzip wird oft als subjektiv bezeichnet.

Das Prinzip kann anhand eines Beispiels gut verstanden werden. Stellen Sie sich vor, es gibt eine Klasse, die folgende Operationen ausführt.

  • Verbunden mit einer Datenbank

  • Lesen Sie einige Daten aus Datenbanktabellen

  • Zum Schluss schreiben Sie es in eine Datei.

Haben Sie sich das Szenario vorgestellt? Hier hat die Klasse mehrere Gründe, sich zu ändern, und nur wenige davon sind die Änderung der Dateiausgabe und die Übernahme neuer Datenbanken. Wenn wir über die Verantwortung eines einzelnen Prinzips sprechen, würden wir sagen, dass es zu viele Gründe für die Änderung der Klasse gibt, daher passt sie nicht richtig in das Prinzip der einzelnen Verantwortung.

Beispielsweise kann eine Automobilklasse sich selbst starten oder stoppen, aber die Aufgabe, sie zu waschen, gehört zur CarWash-Klasse. In einem anderen Beispiel verfügt eine Book-Klasse über Eigenschaften zum Speichern ihres eigenen Namens und Textes. Die Aufgabe des Druckens des Buches muss jedoch zur Klasse der Buchdrucker gehören. Die Buchdruckerklasse druckt möglicherweise auf einer Konsole oder einem anderen Medium, aber solche Abhängigkeiten werden aus der Buchklasse entfernt

Warum ist dieses Prinzip erforderlich?

Wenn das Prinzip der Einzelverantwortung befolgt wird, ist das Testen einfacher. Mit einer einzigen Verantwortung hat die Klasse weniger Testfälle. Weniger Funktionalität bedeutet auch weniger Abhängigkeiten zu anderen Klassen. Dies führt zu einer besseren Code-Organisation, da kleinere und zweckmäßige Klassen einfacher zu suchen sind.

Ein Beispiel zur Verdeutlichung dieses Prinzips:

Angenommen, Sie werden aufgefordert, einen UserSetting-Dienst zu implementieren, bei dem der Benutzer die Einstellungen ändern kann, der Benutzer jedoch zuvor authentifiziert werden muss. Eine Möglichkeit, dies umzusetzen, wäre:

öffentliche Klasse UserSettingService {public void changeEmail (Benutzer Benutzer) {if (checkAccess (Benutzer)) {// Option zum Ändern gewähren}} public boolean checkAccess (Benutzer Benutzer) {// Überprüfen Sie, ob der Benutzer gültig ist. }}

Alles sieht gut aus, bis Sie den checkAccess-Code an einer anderen Stelle wiederverwenden möchten ODER Änderungen an der Art und Weise vornehmen möchten, wie checkAccess ausgeführt wird. In allen zwei Fällen würden Sie am Ende dieselbe Klasse ändern, und im ersten Fall müssten Sie UserSettingService verwenden, um ebenfalls nach dem Zugriff zu suchen.
Eine Möglichkeit, dies zu korrigieren, besteht darin, den UserSettingService in UserSettingService und SecurityService zu zerlegen. Verschieben Sie den checkAccess-Code in SecurityService.

öffentliche Klasse UserSettingService {public void changeEmail (Benutzer Benutzer) {if (SecurityService.checkAccess (Benutzer)) {// Option zum Ändern gewähren}}} öffentliche Klasse SecurityService {öffentlicher statischer boolescher checkAccess (Benutzer Benutzer) {// Überprüfen Sie den Zugriff. }}

Offenes geschlossenes Prinzip in Java

Robert C. Martin beschreibt es als Softwarekomponenten, die zur Erweiterung geöffnet, aber zur Änderung geschlossen sein sollten.

Um genau zu sein, sollte eine Klasse nach diesem Prinzip so geschrieben sein, dass sie ihre Arbeit einwandfrei ausführt, ohne davon auszugehen, dass die Menschen in Zukunft einfach kommen und sie ändern werden. Daher sollte die Klasse wegen Änderungen geschlossen bleiben, aber die Option haben, erweitert zu werden. Möglichkeiten zur Erweiterung der Klasse sind:

  • Von der Klasse erben

  • Überschreiben der erforderlichen Verhaltensweisen aus der Klasse

  • Erweitern bestimmter Verhaltensweisen der Klasse

Ein hervorragendes Beispiel für ein Open-Closed-Prinzip kann mit Hilfe von Browsern verstanden werden. Erinnerst du dich daran, Erweiterungen in deinem Chrome-Browser installiert zu haben?

Die Grundfunktion des Chrome-Browsers besteht darin, auf verschiedenen Websites zu surfen. Möchten Sie die Grammatik überprüfen, wenn Sie eine E-Mail mit dem Chrome-Browser schreiben? Wenn ja, können Sie einfach die Grammatik-Erweiterung verwenden, um die Grammatik des Inhalts zu überprüfen.

Dieser Mechanismus, bei dem Sie Dinge hinzufügen, um die Funktionalität des Browsers zu verbessern, ist eine Erweiterung. Daher ist der Browser ein perfektes Beispiel für Funktionen, die zur Erweiterung geöffnet, aber zur Änderung geschlossen sind. Mit einfachen Worten, Sie können die Funktionalität verbessern, indem Sie Plugins in Ihrem Browser hinzufügen / installieren, aber nichts Neues erstellen.

Warum ist dieses Prinzip erforderlich?

OCP ist wichtig, da Klassen möglicherweise über Bibliotheken von Drittanbietern zu uns kommen. Wir sollten in der Lage sein, diese Klassen zu erweitern, ohne uns Sorgen machen zu müssen, ob diese Basisklassen unsere Erweiterungen unterstützen können. Die Vererbung kann jedoch zu Unterklassen führen, die von der Implementierung der Basisklasse abhängen. Um dies zu vermeiden, wird die Verwendung von Schnittstellen empfohlen. Diese zusätzliche Abstraktion führt zu einer losen Kopplung.

Nehmen wir an, wir müssen Flächen mit verschiedenen Formen berechnen. Wir beginnen mit der Erstellung einer Klasse für unser Rechteck der ersten FormDas hat 2 Attribute Länge& Breite.

public class Rectangle {öffentliche doppelte Länge öffentliche doppelte Breite}

Als nächstes erstellen wir eine Klasse, um die Fläche dieses Rechtecks ​​zu berechnenwelches eine Methode berechneRectangleArea hatdas nimmt das Rechteckals Eingabeparameter und berechnet seine Fläche.

öffentliche Klasse AreaCalculator {public double berechneRectangleArea (Rechteck-Rechteck) {return rechteck.Länge * Rechteck.Breite}}

So weit, ist es gut. Nehmen wir nun an, wir erhalten unseren zweiten Formkreis. Also erstellen wir umgehend einen neuen Klassenkreismit einem einzelnen Attributradius.

öffentliche Klasse Kreis {öffentlicher doppelter Radius}

Dann modifizieren wir AreacalculatorKlasse zum Hinzufügen von Kreisberechnungen durch eine neue Methode berechneCircleaArea ()

öffentliche Klasse AreaCalculator {public double berechneRectangleArea (Rechteck Rechteck) {return rechteck.Länge * rechteck.breite} public double berechneCircleArea (Kreis Kreis) {return (22/7) * Kreis.radius * Kreis.radius}}

Beachten Sie jedoch, dass die oben beschriebene Lösung fehlerhaft war.

Nehmen wir an, wir haben ein neues Fünfeck. In diesem Fall werden wir am Ende erneut die AreaCalculator-Klasse ändern. Wenn die Arten von Formen zunehmen, wird dies unübersichtlicher, da sich AreaCalculator ständig ändert und alle Verbraucher dieser Klasse ihre Bibliotheken, die AreaCalculator enthalten, ständig aktualisieren müssen. Infolgedessen wird die AreaCalculator-Klasse nicht mit Sicherheit als Basis festgelegt (finalisiert), da sie jedes Mal geändert wird, wenn eine neue Form kommt. Daher ist dieses Design nicht für Änderungen geschlossen.

AreaCalculator muss seine Berechnungslogik in neueren Methoden weiter hinzufügen. Wir erweitern den Umfang der Formen nicht wirklich, sondern machen einfach Stück für Stück eine Stück-für-Stück-Lösung für jede hinzugefügte Form.

Änderung des obigen Designs, um dem Öffnungs- / Schließprinzip zu entsprechen:

Lassen Sie uns nun ein eleganteres Design sehen, das die Fehler im obigen Design behebt, indem es sich an das Open / Closed-Prinzip hält. Wir werden zunächst das Design erweiterbar machen. Dazu müssen wir zuerst einen Basistyp Shape definieren und Circle & Rectangle die Shape-Schnittstelle implementieren lassen.

öffentliche Schnittstelle Shape {public double berechneArea ()} öffentliche Klasse Rechteck implementiert Form {doppelte Länge doppelte Breite public double berechneArea () {Rückgabelänge * Breite}} öffentliche Klasse Kreis implementiert Form {öffentlicher doppelter Radius public double berechneArea () {return (22 / 7) * Radius * Radius}}

Es gibt eine Basisschnittstellenform. Alle Formen implementieren jetzt die Basisschnittstellenform. Die Formschnittstelle verfügt über eine abstrakte Methode berechneArea (). Sowohl Kreis als auch Rechteck bieten eine eigene überschriebene Implementierung der Methode berechneArea () unter Verwendung ihrer eigenen Attribute.
Wir haben ein gewisses Maß an Erweiterbarkeit eingeführt, da Formen jetzt eine Instanz von Formschnittstellen sind. Dies ermöglicht es uns, Shape anstelle einzelner Klassen zu verwenden
Der letzte Punkt oben erwähnte Verbraucher dieser Formen. In unserem Fall ist der Verbraucher die AreaCalculator-Klasse, die nun so aussehen würde.

öffentliche Klasse AreaCalculator {public double berechneShapeArea (Formform) {return shape.calculateArea ()}}

Dieser AreaCalculatorclass beseitigt jetzt unsere oben genannten Konstruktionsfehler vollständig und bietet eine saubere Lösung, die dem Open-Closed-Prinzip entspricht. Fahren wir mit anderen SOLID-Prinzipien in Java fort

Liskov-Substitutionsprinzip in Java

Robert C. Martin beschreibt es als Abgeleitete Typen müssen ihre Basistypen vollständig ersetzen können.

Das Liskov-Substitutionsprinzip nimmt an, dass q (x) eine Eigenschaft ist, die über Entitäten von x, die zum Typ T gehören, beweisbar ist. Nach diesem Prinzip sollte nun q (y) für Objekte y beweisbar sein, die zum Typ S gehören, und Das S ist eigentlich ein Subtyp von T. Sind Sie jetzt verwirrt und wissen nicht, was das Liskov-Substitutionsprinzip tatsächlich bedeutet? Die Definition mag etwas komplex sein, aber in der Tat ist es ziemlich einfach. Das einzige ist, dass jede Unterklasse oder abgeleitete Klasse durch ihre übergeordnete oder Basisklasse ersetzt werden sollte.

Man kann sagen, dass es sich um ein einzigartiges objektorientiertes Prinzip handelt. Das Prinzip kann durch einen Kindertyp eines bestimmten Elterntyps weiter vereinfacht werden, ohne dass Komplikationen auftreten oder Dinge in die Luft gejagt werden sollten, die für diesen Elternteil eintreten können. Dieses Prinzip ist eng mit dem Liskov-Substitutionsprinzip verwandt.

Warum ist dieses Prinzip erforderlich?

Dies vermeidet den Missbrauch der Vererbung. Es hilft uns, uns an die „Ist-Eine“ -Beziehung anzupassen. Wir können auch sagen, dass Unterklassen einen von der Basisklasse definierten Vertrag erfüllen müssen. In diesem Sinne ist es verwandt mitDesign by Contractdas wurde zuerst von Bertrand Meyer beschrieben. Es ist beispielsweise verlockend zu sagen, dass ein Kreis eine Art Ellipse ist, Kreise jedoch keine zwei Brennpunkte oder Haupt- / Nebenachsen haben.

Der LSP wird im Volksmund am Beispiel eines Quadrats und eines Rechtecks ​​erklärt. wenn wir eine ISA-Beziehung zwischen Square und Rectangle annehmen. Daher nennen wir 'Quadrat ist ein Rechteck'. Der folgende Code repräsentiert die Beziehung.

public class Rectangle {private int length private int width public int getLength () {return length} public void setLength (int length) {this.length = length} public int getBreadth () {return width} public void setBreadth (int width) { this.breadth = width} public int getArea () {return this.length * this.breadth}}

Unten ist der Code für Square. Beachten Sie, dass das Quadrat das Rechteck erweitert.

public class Square erweitert Rectangle {public void setBreadth (int width) {super.setBreadth (width) super.setLength (width)} public void setLength (int length) {super.setLength (length) super.setBreadth (length)}}

In diesem Fall versuchen wir, eine ISA-Beziehung zwischen Square und Rectangle herzustellen, sodass sich der Aufruf von 'Square is a Rectangle' im folgenden Code unerwartet verhält, wenn eine Instanz von Square übergeben wird. Ein Assertionsfehler wird ausgelöst, wenn nach 'Bereich' und nach 'Breite' gesucht wird, obwohl das Programm beendet wird, wenn der Assertionsfehler aufgrund des Fehlschlags der Bereichsprüfung ausgelöst wird.

öffentliche Klasse LSPDemo {public void berechneArea (Rechteck r) {r.setBreadth (2) r.setLength (3) assert r.getArea () == 6: printError ('area', r) assert r.getLength () == 3: printError ('length', r) assert r.getBreadth () == 2: printError ('width', r)} privater String printError (String errorIdentifer, Rectangle r) {return 'Unerwarteter Wert von' + errorIdentifer + ' Zum Beispiel von '+ r.getClass (). getName ()} public static void main (String [] args) {LSPDemo lsp = new LSPDemo () // Eine Instanz von Rectangle wird übergeben lsp.calculateArea (new Rectangle ()) // Eine Instanz von Square wird übergeben lsp.calculateArea (new Square ())}}

Die Klasse demonstriert das Liskov-Substitutionsprinzip (LSP) Gemäß dem Prinzip müssen die Funktionen, die Verweise auf die Basisklassen verwenden, Objekte der abgeleiteten Klasse verwenden können, ohne es zu wissen.

In dem unten gezeigten Beispiel sollte die Funktion berechne Fläche, die die Referenz von 'Rechteck' verwendet, in der Lage sein, die Objekte einer abgeleiteten Klasse wie 'Quadrat' zu verwenden und die Anforderungen der Rechteckdefinition zu erfüllen. Man sollte beachten, dass gemäß der Definition von Rechteck Folgendes angesichts der folgenden Daten immer zutreffen muss:

  1. Die Länge muss immer der Länge entsprechen, die als Eingabe für die Methode setLength übergeben wurde
  2. Die Breite muss immer der Breite entsprechen, die als Eingabe für die Methode setBreadth übergeben wird
  3. Die Fläche muss immer gleich dem Produkt aus Länge und Breite sein

Falls wir versuchen, eine ISA-Beziehung zwischen Square und Rectangle herzustellen, so dass wir 'Square is a Rectangle' nennen, verhält sich der obige Code unerwartet, wenn eine Instanz von Square übergeben wird. Bei der Überprüfung auf Fläche und Überprüfung wird ein Assertionsfehler ausgegeben für die Breite, obwohl das Programm beendet wird, wenn der Assertionsfehler aufgrund eines Fehlers der Bereichsprüfung ausgelöst wird.

Die Square-Klasse benötigt keine Methoden wie setBreadth oder setLength. Die LSPDemo-Klasse müsste die Details der abgeleiteten Rechteckklassen (z. B. Square) kennen, um einen geeigneten Code zu erhalten, um Fehler zu vermeiden. Die Änderung des bestehenden Codes verstößt in erster Linie gegen das Open-Closed-Prinzip.

Prinzip der Schnittstellentrennung

Robert C. Martin beschreibt es so, dass Kunden nicht gezwungen werden sollten, unnötige Methoden zu implementieren, die sie nicht verwenden werden.

GemäßPrinzip der Schnittstellentrennungein Client, egal was niemals gezwungen werden sollte, eine Schnittstelle zu implementieren, die er nicht verwendet, oder der Client sollte niemals gezwungen sein, sich auf eine Methode zu verlassen, die von ihm nicht verwendet wird. Grundsätzlich also die Prinzipien der Schnittstellentrennung, wie Sie sie bevorzugen Schnittstellen, die klein, aber kundenspezifisch sind, anstatt monolithische und größere Schnittstellen. Kurz gesagt, es wäre schlecht für Sie, den Kunden zu zwingen, von einer bestimmten Sache abhängig zu sein, die er nicht benötigt.

Beispielsweise ist eine einzelne Protokollierungsschnittstelle zum Schreiben und Lesen von Protokollen für eine Datenbank nützlich, nicht jedoch für eine Konsole. Das Lesen von Protokollen macht für einen Konsolenlogger keinen Sinn. Fahren Sie mit diesem Artikel zu SOLID Principles in Java fort.

Warum ist dieses Prinzip erforderlich?

Nehmen wir an, es gibt eine Restaurant-Oberfläche, die Methoden zum Akzeptieren von Bestellungen von Online-Kunden, Einwahl- oder Telefonkunden und Walk-In-Kunden enthält. Es enthält auch Methoden zur Abwicklung von Online-Zahlungen (für Online-Kunden) und persönlichen Zahlungen (für Walk-In-Kunden sowie Telefonkunden, wenn ihre Bestellung zu Hause geliefert wird).

Erstellen wir nun eine Java-Schnittstelle für das Restaurant und nennen sie RestaurantInterface.java.

öffentliche Schnittstelle RestaurantInterface {public void acceptOnlineOrder () public void takeTelephoneOrder () public void payOnline () public void walkInCustomerOrder () public void payInPerson ()}

In RestaurantInterface sind 5 Methoden definiert, mit denen Sie Online-Bestellungen annehmen, telefonische Bestellungen entgegennehmen, Bestellungen von einem begehbaren Kunden annehmen, Online-Zahlungen annehmen und Zahlungen persönlich annehmen können.

Beginnen wir mit der Implementierung des RestaurantInterface für Online-Kunden als OnlineClientImpl.java

public class OnlineClientImpl implementiert RestaurantInterface {public void acceptOnlineOrder () {// Logik für die Online-Bestellung} public void takeTelephoneOrder () {// Nicht für Online-Bestellungen anwendbar throw new UnsupportedOperationException ()} public void payOnline () {// Logik zum Bezahlen online} public void walkInCustomerOrder () {// Nicht anwendbar für Online-Bestellungen werfen neue UnsupportedOperationException ()} public void payInPerson () {// Nicht anwendbar für Online-Bestellungen werfen neue UnsupportedOperationException ()}}
  • Da der obige Code (OnlineClientImpl.java) für Online-Bestellungen gilt, lösen Sie UnsupportedOperationException aus.

  • Online-, Telefon- und Walk-In-Clients verwenden die jeweils spezifische RestaurantInterface-Implementierung.

  • Die Implementierungsklassen für den Telefon-Client und den Walk-In-Client verfügen über nicht unterstützte Methoden.

    Erstellen Sie einen Parameter in Tableau
  • Da die 5 Methoden Teil des RestaurantInterface sind, müssen die Implementierungsklassen alle 5 implementieren.

  • Die Methoden, die jede der Implementierungsklassen UnsupportedOperationException auslöst. Wie Sie deutlich sehen können, ist die Implementierung aller Methoden ineffizient.

  • Jede Änderung an einer der Methoden des RestaurantInterface wird an alle Implementierungsklassen weitergegeben. Die Wartung des Codes wird dann sehr umständlich und die Regressionseffekte von Änderungen werden weiter zunehmen.

  • RestaurantInterface.java verstößt gegen das Prinzip der Einzelverantwortung, da die Logik für Zahlungen sowie die für die Auftragserteilung in einer einzigen Schnittstelle zusammengefasst sind.

Um die oben genannten Probleme zu lösen, wenden wir das Prinzip der Schnittstellentrennung an, um das obige Design zu überarbeiten.

  1. Teilen Sie die Funktionen für Zahlung und Auftragserteilung in zwei separate Lean-Schnittstellen auf: PaymentInterface.java und OrderInterface.java.

  2. Jeder der Clients verwendet jeweils eine Implementierung von PaymentInterface und OrderInterface. Beispiel: OnlineClient.java verwendet OnlinePaymentImpl und OnlineOrderImpl usw.

  3. Das Prinzip der Einzelverantwortung ist jetzt als Zahlungsschnittstelle (PaymentInterface.java) und Bestellschnittstelle (OrderInterface) angehängt.

  4. Änderungen an einer der Bestell- oder Zahlungsschnittstellen wirken sich nicht auf die andere aus. Sie sind jetzt unabhängig. Es ist nicht erforderlich, eine Dummy-Implementierung durchzuführen oder eine UnsupportedOperationException auszulösen, da jede Schnittstelle nur Methoden enthält, die immer verwendet werden.

Nach der Bewerbung des ISP

Prinzip der Abhängigkeitsinversion

Robert C. Martin beschreibt es so, dass es von Abstraktionen und nicht von Konkretionen abhängt. Demnach darf sich das High-Level-Modul niemals auf ein Low-Level-Modul verlassen. beispielsweise

Sie gehen in ein Geschäft vor Ort, um etwas zu kaufen, und Sie entscheiden sich dafür, es mit Ihrer Debitkarte zu bezahlen. Wenn Sie dem Sachbearbeiter Ihre Karte zur Zahlung geben, muss der Sachbearbeiter nicht überprüfen, welche Art von Karte Sie gegeben haben.

Selbst wenn Sie eine Visa-Karte gegeben haben, wird er keinen Visa-Automaten zum Durchziehen Ihrer Karte ausstellen. Die Art der Kreditkarte oder Debitkarte, die Sie zum Bezahlen haben, spielt keine Rolle, sie wird einfach durchgestrichen. In diesem Beispiel können Sie also sehen, dass sowohl Sie als auch der Sachbearbeiter von der Kreditkartenabstraktion abhängig sind und Sie sich keine Sorgen über die Besonderheiten der Karte machen. Dies ist ein Prinzip der Abhängigkeitsinversion.

Warum ist dieses Prinzip erforderlich?

Es ermöglicht einem Programmierer, fest codierte Abhängigkeiten zu entfernen, so dass die Anwendung lose gekoppelt und erweiterbar wird.

öffentliche Klasse Student {private Adresse Adresse public Student () {Adresse = neue Adresse ()}}

Im obigen Beispiel benötigt die Student-Klasse ein Adressobjekt und ist für die Initialisierung und Verwendung des Adressobjekts verantwortlich. Wenn die Adressklasse in Zukunft geändert wird, müssen wir auch Änderungen in der Schülerklasse vornehmen. Dies macht die enge Kopplung zwischen Schüler- und Adressobjekten. Wir können dieses Problem mithilfe des Entwurfsmusters für die Abhängigkeitsinversion lösen. Das Adressobjekt wird unabhängig implementiert und dem Schüler bereitgestellt, wenn der Schüler durch Verwendung einer konstruktorbasierten oder setzerbasierten Abhängigkeitsinversion instanziiert wird.

Damit sind wir mit diesen SOLID-Prinzipien in Java fertig.

Besuche die von Edureka, einem vertrauenswürdigen Online-Lernunternehmen mit einem Netzwerk von mehr als 250.000 zufriedenen Lernenden auf der ganzen Welt. Der Java J2EE- und SOA-Schulungs- und Zertifizierungskurs von Edureka richtet sich an Studenten und Fachleute, die Java-Entwickler werden möchten. Der Kurs soll Ihnen einen Vorsprung in die Java-Programmierung verschaffen und Sie sowohl für grundlegende als auch für fortgeschrittene Java-Konzepte sowie für verschiedene Java-Frameworks wie Hibernate & Spring schulen.

Hast du eine Frage an uns? Bitte erwähnen Sie dies im Kommentarbereich dieses Blogs „SOLID Principles in Java“. Wir werden uns so schnell wie möglich bei Ihnen melden.