Appearance
Solid Principals
Single Responsibility Principle (SRP)
- Eine Klasse sollte nur eine einzige Verantwortung bzw. Aufgabe haben
SRP Antibeispiel:
Weil der Controller sowohl Anfragen entgegennimmt als auch die Businesslogik enthältjava
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AntiController {
@GetMapping("/request")
public void handleRequest() {
handleRequestService();
}
private void handleRequestService() {
// Business logic
}
}Open/Closed Principle (OCP)
- Die Software sollte offen sein für erweiterung aber geschlossen für änderungen
OCP Antibeispiel:
Erweiterung der Klasse AntiShape erfordert Änderungen an der calculateArea Methodejava
public class AntiShape {
public double calculateArea(Object shape) {
if (shape instanceof Circle) {
Circle circle = (Circle) shape;
return Math.PI * Math.pow(circle.getRadius(), 2);
} else if (shape instanceof Rectangle) {
Rectangle rectangle = (Rectangle) shape;
return rectangle.getWidth() * rectangle.getHeight();
}
throw new IllegalArgumentException("Unknown shape");
}
}Liskov Substitution Principle (LSP)
- Eine Unterklasse sollte eine Oberklasse ohne Probleme ersetzen können
LSP Antibeispiel:
Weil die Unterklasse Square die Methode setWidth und setHeight überschreibt, führt dies zu unerwartetem Verhalten, wenn sie als Rectangle verwendet wirdjava
public class Rectangle {
protected double width;
protected double height;
public void setWidth(double width) {
this.width = width;
}
public void setHeight(double height) {
this.height = height;
}
public double getArea() {
return width * height;
}
}
public class Square extends Rectangle {
@Override
public void setWidth(double width) {
this.width = width;
this.height = width; // Square hat gleiche Breite und Höhe
}
@Override
public void setHeight(double height) {
this.height = height;
this.width = height; // Square hat gleiche Breite und Höhe
}
}Interface Segregation Principle (ISP)
- Clients sollten nicht gezwungen sein, Schnittstellen zu implementieren, die sie nicht verwenden
- Daraus folgt lieber mehrere kleine Interfaces statt ein riesen Interface
ISP Antibeispiel:
Ein Drucker der Farbdruck nicht unterstützt müsste dieses trotzdem implementierenjava
public interface AntiPrinter {
void printBlackAndWhite(String content);
void printColor(String content);
}Dependency Inversion Principle (DIP)
- Keine Abhängigkeiten von konkreten Klassen, sondern von Abstraktionen (Interfaces oder abstrakte Klassen)
DIP Antibeispiel:
Weil die Klasse AntiService direkt von der konkreten Implementierung AntiRepository abhängt, ist es schwierig, die Implementierung zu ändern oder zu testen, ohne die AntiService-Klasse zu modifizierenjava
public class AntiRepository {
public String fetchData() {
return "Data from repository";
}
}besser mit Dependency injection siehe
Literatur
- Der Weg zum Java Profi Auflage 5
- Kapitel 3.5.3 (S.167)