In Java, SOLIDE Prinzipien sind ein objektorientierter Ansatz, der auf den Entwurf von Softwarestrukturen angewendet wird. Es wird konzeptualisiert von Robert C. Martin (auch bekannt als Onkel Bob). Diese fünf Prinzipien haben die Welt der objektorientierten Programmierung und auch die Art und Weise, Software zu schreiben, verändert. Es stellt außerdem sicher, dass die Software modular, leicht zu verstehen, zu debuggen und umzugestalten ist. In diesem Abschnitt werden wir diskutieren SOLID-Prinzipien in Java mit richtigem Beispiel .
Das Wort SOLID ist ein Akronym für:
- Prinzip der Einzelverantwortung (SRP)
- Open-Closed-Prinzip (OCP)
- Liskov-Substitutionsprinzip (LSP)
- Prinzip der Schnittstellentrennung (ISP)
- Abhängigkeitsinversionsprinzip (DIP)
Lassen Sie uns die Prinzipien einzeln im Detail erklären.
Prinzip der Einzelverantwortung
Das Prinzip der Einzelverantwortung besagt dies Jede Java-Klasse muss eine einzelne Funktionalität ausführen . Die Implementierung mehrerer Funktionalitäten in einer einzelnen Klasse führt zu einem Mashup des Codes und wenn eine Änderung erforderlich ist, kann dies Auswirkungen auf die gesamte Klasse haben. Es präzisiert den Code und der Code kann leicht gepflegt werden. Lassen Sie uns das Prinzip der Einzelverantwortung anhand eines Beispiels verstehen.
Vermuten, Student ist eine Klasse mit drei Methoden, nämlich printDetails(), berechnePercentage(), Und addStudent(). Daher hat die Klasse „Student“ drei Aufgaben: die Details der Schüler auszudrucken, Prozentsätze zu berechnen und eine Datenbank zu erstellen. Durch die Verwendung des Prinzips der Einzelverantwortung können wir diese Funktionalitäten in drei separate Klassen unterteilen, um das Ziel des Prinzips zu erreichen.
Student.java
public class Student { public void printDetails(); { //functionality of the method } pubic void calculatePercentage(); { //functionality of the method } public void addStudent(); { //functionality of the method } }
Der obige Codeausschnitt verstößt gegen das Prinzip der Einzelverantwortung. Um das Ziel des Prinzips zu erreichen, sollten wir eine separate Klasse implementieren, die nur eine einzige Funktionalität ausführt.
Kat Timpf Höhe
Student.java
public class Student { public void addStudent(); { //functionality of the method } }
PrintStudentDetails.java
public class PrintStudentDetails { public void printDetails(); { //functionality of the method } }
Prozentsatz.java
public class Percentage { public void calculatePercentage(); { //functionality of the method } }
Daher haben wir das Ziel des Single-Responsibility-Prinzips erreicht, indem wir die Funktionalität in drei separate Klassen unterteilt haben.
Offen-Geschlossen-Prinzip
Die Anwendung oder das Modul entitäten die Methoden, Funktionen, Variablen usw. Das Offen-Geschlossen-Prinzip besagt, dass entsprechend neuen Anforderungen Das Modul sollte für Erweiterungen geöffnet, für Änderungen jedoch geschlossen sein. Die Erweiterung ermöglicht es uns, neue Funktionen in das Modul zu implementieren. Lassen Sie uns das Prinzip anhand eines Beispiels verstehen.
Vermuten, FahrzeugInfo ist eine Klasse und hat die Methode Fahrzeugnummer() das gibt die Fahrzeugnummer zurück.
CSS-Übergangsdeckkraft
VehicleInfo.java
public class VehicleInfo { public double vehicleNumber(Vehicle vcl) { if (vcl instanceof Car) { return vcl.getNumber(); if (vcl instanceof Bike) { return vcl.getNumber(); } }
Wenn wir eine weitere Unterklasse namens Truck hinzufügen möchten, fügen wir einfach eine weitere if-Anweisung hinzu, die gegen das Open-Closed-Prinzip verstößt. Die einzige Möglichkeit, die Unterklasse hinzuzufügen und das Ziel des Prinzips zu erreichen, besteht darin, die zu überschreiben Fahrzeugnummer() Methode, wie wir unten gezeigt haben.
VehicleInfo.java
public class VehicleInfo { public double vehicleNumber() { //functionality } } public class Car extends VehicleInfo { public double vehicleNumber() { return this.getValue(); } public class Car extends Truck { public double vehicleNumber() { return this.getValue(); }
Ebenso können wir weitere Fahrzeuge hinzufügen, indem wir eine weitere Unterklasse erstellen, die von der Fahrzeugklasse ausgeht. Der Ansatz hätte keine Auswirkungen auf die bestehende Anwendung.
Liskov-Substitutionsprinzip
Das Liskov-Substitutionsprinzip (LSP) wurde eingeführt von Barbara Liskov . Es gilt für die Erbschaft in der Weise, dass die Abgeleitete Klassen müssen ihre Basisklassen vollständig ersetzen können . Mit anderen Worten: Wenn Klasse A ein Untertyp von Klasse B ist, sollten wir in der Lage sein, B durch A zu ersetzen, ohne das Verhalten des Programms zu unterbrechen.
Es erweitert das Open-Close-Prinzip und konzentriert sich auch auf das Verhalten einer Oberklasse und ihrer Untertypen. Wir sollten die Klassen so entwerfen, dass die Eigenschaft erhalten bleibt, es sei denn, wir haben einen triftigen Grund, etwas anderes zu tun. Lassen Sie uns das Prinzip anhand eines Beispiels verstehen.
Student.java
public class Student { private double height; private double weight; public void setHeight(double h) { height = h; } public void setWeight(double w) { weight= w; } ... } public class StudentBMI extends Student { public void setHeight(double h) { super.setHeight(h); super.setWeight(w); } public void setWeight(double h) { super.setHeight(h); super.setWeight(w); } }
Die oben genannten Klassen verstießen gegen das Liskov-Substitutionsprinzip, da die Klasse StudentBMI zusätzliche Einschränkungen hat, d. h. Größe und Gewicht müssen gleich sein. Daher kann die Student-Klasse (Basisklasse) nicht durch die StudentBMI-Klasse (abgeleitete Klasse) ersetzt werden.
undefinierte Steigung
Daher kann das Ersetzen der Klasse „Student“ durch die Klasse „StudentBMI“ zu unerwartetem Verhalten führen.
Prinzip der Schnittstellentrennung
Das Prinzip besagt, dass sich die größeren Schnittstellen in kleinere aufspalten. Denn die Implementierungsklassen verwenden nur die Methoden, die benötigt werden. Wir sollten den Kunden nicht dazu zwingen, Methoden zu verwenden, die er nicht verwenden möchte.
Das Ziel des Interface-Segregation-Prinzips ähnelt dem Single-Responsibility-Prinzip. Lassen Sie uns das Prinzip anhand eines Beispiels verstehen.
Java-Swing-Tutorial
Angenommen, wir haben eine Schnittstelle mit dem Namen erstellt Konvertierung drei Methoden haben intToDouble(), intToChar(), Und charToString() .
public interface Conversion { public void intToDouble(); public void intToChar(); public void charToString(); }
Die obige Schnittstelle verfügt über drei Methoden. Wenn wir nur eine Methode intToChar() verwenden möchten, haben wir keine Wahl, die einzelne Methode zu implementieren. Um das Problem zu lösen, erlaubt uns das Prinzip, die Schnittstelle in drei separate aufzuteilen.
public interface ConvertIntToDouble { public void intToDouble(); } public interface ConvertIntToChar { public void intToChar(); } public interface ConvertCharToString { public void charToString(); }
Jetzt können wir nur die Methode verwenden, die erforderlich ist. Angenommen, wir möchten eine Ganzzahl in ein Double und ein Zeichen in eine Zeichenfolge konvertieren. Dann verwenden wir nur die Methoden intToDouble() Und charToString().
public class DataTypeConversion implements ConvertIntToDouble, ConvertCharToString { public void intToDouble() { //conversion logic } public void charToString() { //conversion logic } }
Abhängigkeitsinversionsprinzip
Das Prinzip besagt, dass wir Abstraktion (abstrakte Klassen und Schnittstellen) anstelle konkreter Implementierungen verwenden müssen. High-Level-Module sollten nicht vom Low-Level-Modul abhängen, aber beide sollten von der Abstraktion abhängen. Denn die Abstraktion hängt nicht vom Detail ab, sondern das Detail hängt von der Abstraktion ab. Es entkoppelt die Software. Lassen Sie uns das Prinzip anhand eines Beispiels verstehen.
public class WindowsMachine { //functionality }
Es lohnt sich, wenn wir keine Tastatur und Maus haben, um unter Windows zu arbeiten. Um dieses Problem zu lösen, erstellen wir einen Konstruktor der Klasse und fügen die Instanzen der Tastatur und des Monitors hinzu. Nach dem Hinzufügen der Instanzen sieht die Klasse wie folgt aus:
public class WindowsMachine { public final keyboard; public final monitor; public WindowsMachine() { monitor = new monitor(); //instance of monitor class keyboard = new keyboard(); //instance of keyboard class } }
Jetzt können wir mit Hilfe von Tastatur und Maus auf dem Windows-Rechner arbeiten. Aber wir stehen immer noch vor dem Problem. Weil wir die drei Klassen durch die Verwendung des neuen Schlüsselworts eng miteinander verknüpft haben. Es ist schwierig, die Klasse Windows-Maschine zu testen.
Um den Code lose zu koppeln, entkoppeln wir die WindowsMachine von der Tastatur, indem wir die Tastaturschnittstelle und dieses Schlüsselwort verwenden.
Tastatur.java
Geschichte in Java
public interface Keyboard { //functionality }
WindowsMachine.java
public class WindowsMachine { private final Keyboard keyboard; private final Monitor monitor; public WindowsMachine(Keyboard keyboard, Monitor monitor) { this.keyboard = keyboard; this.monitor = monitor; } }
Im obigen Code haben wir die Abhängigkeitsinjektion verwendet, um die Tastaturabhängigkeit in der WindowsMachine-Klasse hinzuzufügen. Daher haben wir die Klassen entkoppelt.
Warum sollten wir SOLID-Prinzipien verwenden?
- Es reduziert die Abhängigkeiten, sodass ein Codeblock geändert werden kann, ohne dass sich dies auf die anderen Codeblöcke auswirkt.
- Die Prinzipien sollen Design einfacher und verständlicher machen.
- Durch die Anwendung der Prinzipien ist das System wartbar, testbar, skalierbar und wiederverwendbar.
- Es vermeidet das schlechte Design der Software.
Wenn Sie das nächste Mal Software entwerfen, sollten Sie diese fünf Prinzipien im Hinterkopf behalten. Durch die Anwendung dieser Prinzipien wird der Code viel klarer, testbarer und entbehrlicher.