SOLID Prinzipien für bessere Software | Enjyn Gruppe
Hallo Welt
→
→
Hallo Welt
Original Lingva Deutsch
Übersetzung wird vorbereitet...
Dieser Vorgang kann bis zu 60 Sekunden dauern.
Diese Seite wird erstmalig übersetzt und dann für alle Besucher gespeichert.
0%
DE Zurück zu Deutsch
Übersetzung durch Lingva Translate

330 Dokumentationen verfügbar

Wissensdatenbank

SOLID Prinzipien Erklärt

Zuletzt aktualisiert: 14.07.2026 um 12:29 Uhr

SOLID Prinzipien für bessere Software

SOLID ist ein Akronym für fünf Designprinzipien objektorientierter Programmierung. Sie führen zu wartbarem, flexiblem und testbarem Code.

Überblick

Buchstabe Prinzip Kurzform
S Single Responsibility Eine Klasse, eine Aufgabe
O Open/Closed Offen für Erweiterung, geschlossen für Änderung
L Liskov Substitution Subtypen müssen ersetzbar sein
I Interface Segregation Kleine, spezifische Interfaces
D Dependency Inversion Abhängig von Abstraktionen, nicht Konkretionen

S - Single Responsibility Principle

// "Eine Klasse sollte nur einen Grund haben, sich zu ändern."

// ❌ Verletzt SRP - Klasse macht zu viel
class User {
    public function __construct(
        public string $name,
        public string $email
    ) {}

    public function save() {
        // Datenbank-Logik
        $db->insert('users', $this->toArray());
    }

    public function sendWelcomeEmail() {
        // Email-Logik
        $mailer->send($this->email, 'Welcome!', ...);
    }

    public function generateReport() {
        // Report-Logik
        return new PDF($this->toArray());
    }
}

// ✅ SRP eingehalten - Jede Klasse hat eine Verantwortung
class User {
    public function __construct(
        public string $name,
        public string $email
    ) {}
}

class UserRepository {
    public function save(User $user): void {
        $this->db->insert('users', $user->toArray());
    }

    public function findById(int $id): ?User {
        // ...
    }
}

class UserMailer {
    public function sendWelcomeEmail(User $user): void {
        $this->mailer->send($user->email, 'Welcome!', ...);
    }
}

class UserReportGenerator {
    public function generate(User $user): PDF {
        return new PDF($user->toArray());
    }
}

O - Open/Closed Principle

// "Software-Entitäten sollten offen für Erweiterung,
//  aber geschlossen für Modifikation sein."

// ❌ Verletzt OCP - Muss bei jedem neuen Typ geändert werden
class DiscountCalculator {
    public function calculate(Order $order): float {
        if ($order->customerType === 'regular') {
            return $order->total * 0.1;
        } elseif ($order->customerType === 'premium') {
            return $order->total * 0.2;
        } elseif ($order->customerType === 'vip') {
            return $order->total * 0.3;
        }
        // Neue Typen erfordern Änderung dieser Klasse!
        return 0;
    }
}

// ✅ OCP eingehalten - Erweiterbar ohne Änderung
interface DiscountStrategy {
    public function calculate(Order $order): float;
}

class RegularDiscount implements DiscountStrategy {
    public function calculate(Order $order): float {
        return $order->total * 0.1;
    }
}

class PremiumDiscount implements DiscountStrategy {
    public function calculate(Order $order): float {
        return $order->total * 0.2;
    }
}

class VIPDiscount implements DiscountStrategy {
    public function calculate(Order $order): float {
        return $order->total * 0.3;
    }
}

// Neue Typen: Einfach neue Klasse erstellen!
class EmployeeDiscount implements DiscountStrategy {
    public function calculate(Order $order): float {
        return $order->total * 0.5;
    }
}

class DiscountCalculator {
    public function __construct(
        private DiscountStrategy $strategy
    ) {}

    public function calculate(Order $order): float {
        return $this->strategy->calculate($order);
    }
}

L - Liskov Substitution Principle

// "Objekte einer Superklasse sollten durch Objekte einer
//  Subklasse ersetzbar sein, ohne das Programm zu brechen."

// ❌ Verletzt LSP - Square verhält sich anders als erwartet
class Rectangle {
    protected int $width;
    protected int $height;

    public function setWidth(int $width): void {
        $this->width = $width;
    }

    public function setHeight(int $height): void {
        $this->height = $height;
    }

    public function getArea(): int {
        return $this->width * $this->height;
    }
}

class Square extends Rectangle {
    // Quadrat muss beide Seiten gleich halten
    public function setWidth(int $width): void {
        $this->width = $width;
        $this->height = $width;  // Unerwartetes Verhalten!
    }

    public function setHeight(int $height): void {
        $this->width = $height;  // Unerwartetes Verhalten!
        $this->height = $height;
    }
}

// Problem:
$rect = new Square();
$rect->setWidth(5);
$rect->setHeight(10);
echo $rect->getArea();  // Erwartet: 50, Tatsächlich: 100!

// ✅ LSP eingehalten - Separate Hierarchie
interface Shape {
    public function getArea(): int;
}

class Rectangle implements Shape {
    public function __construct(
        private int $width,
        private int $height
    ) {}

    public function getArea(): int {
        return $this->width * $this->height;
    }
}

class Square implements Shape {
    public function __construct(
        private int $side
    ) {}

    public function getArea(): int {
        return $this->side * $this->side;
    }
}

I - Interface Segregation Principle

// "Clients sollten nicht gezwungen werden, von Interfaces
//  abzuhängen, die sie nicht nutzen."

// ❌ Verletzt ISP - Zu großes Interface
interface Worker {
    public function work(): void;
    public function eat(): void;
    public function sleep(): void;
    public function code(): void;
    public function attendMeeting(): void;
}

class Developer implements Worker {
    public function work(): void { /* ... */ }
    public function eat(): void { /* ... */ }
    public function sleep(): void { /* ... */ }
    public function code(): void { /* ... */ }
    public function attendMeeting(): void { /* ... */ }
}

class Robot implements Worker {
    public function work(): void { /* ... */ }
    public function eat(): void {
        // Roboter essen nicht!
        throw new Exception('Robots dont eat');
    }
    public function sleep(): void {
        throw new Exception('Robots dont sleep');
    }
    // ...
}

// ✅ ISP eingehalten - Kleine, fokussierte Interfaces
interface Workable {
    public function work(): void;
}

interface Feedable {
    public function eat(): void;
}

interface Sleepable {
    public function sleep(): void;
}

interface Programmer {
    public function code(): void;
}

class Developer implements Workable, Feedable, Sleepable, Programmer {
    public function work(): void { /* ... */ }
    public function eat(): void { /* ... */ }
    public function sleep(): void { /* ... */ }
    public function code(): void { /* ... */ }
}

class Robot implements Workable {
    public function work(): void { /* ... */ }
    // Keine unnötigen Methoden!
}

D - Dependency Inversion Principle

// "High-Level-Module sollten nicht von Low-Level-Modulen abhängen.
//  Beide sollten von Abstraktionen abhängen."

// ❌ Verletzt DIP - Direkte Abhängigkeit
class OrderService {
    private MySQLDatabase $database;
    private SMTPMailer $mailer;

    public function __construct() {
        $this->database = new MySQLDatabase();  // Konkrete Klasse!
        $this->mailer = new SMTPMailer();       // Konkrete Klasse!
    }

    public function createOrder(Order $order): void {
        $this->database->insert('orders', $order);
        $this->mailer->send($order->customerEmail, 'Order confirmed');
    }
}

// ✅ DIP eingehalten - Abhängig von Abstraktionen
interface DatabaseInterface {
    public function insert(string $table, array $data): void;
}

interface MailerInterface {
    public function send(string $to, string $message): void;
}

class OrderService {
    public function __construct(
        private DatabaseInterface $database,
        private MailerInterface $mailer
    ) {}

    public function createOrder(Order $order): void {
        $this->database->insert('orders', $order->toArray());
        $this->mailer->send($order->customerEmail, 'Order confirmed');
    }
}

// Konkrete Implementierungen
class MySQLDatabase implements DatabaseInterface {
    public function insert(string $table, array $data): void { /* ... */ }
}

class PostgreSQLDatabase implements DatabaseInterface {
    public function insert(string $table, array $data): void { /* ... */ }
}

// Einfach austauschbar!
$service = new OrderService(
    new PostgreSQLDatabase(),  // Leicht wechselbar
    new SendGridMailer()       // Leicht wechselbar
);

// Einfach testbar!
$service = new OrderService(
    new InMemoryDatabase(),    // Test-Double
    new FakeMailer()           // Test-Double
);

Zusammenspiel der Prinzipien

// Alle SOLID Prinzipien in einem Beispiel

// Interfaces (I, D)
interface PaymentProcessor {
    public function process(Payment $payment): PaymentResult;
}

interface PaymentLogger {
    public function log(Payment $payment, PaymentResult $result): void;
}

// Konkrete Implementierungen (O, L)
class StripeProcessor implements PaymentProcessor {
    public function process(Payment $payment): PaymentResult {
        // Stripe-spezifische Logik
    }
}

class PayPalProcessor implements PaymentProcessor {
    public function process(Payment $payment): PaymentResult {
        // PayPal-spezifische Logik
    }
}

// Single Responsibility (S)
class PaymentService {
    public function __construct(
        private PaymentProcessor $processor,  // DIP
        private PaymentLogger $logger
    ) {}

    public function pay(Payment $payment): PaymentResult {
        $result = $this->processor->process($payment);
        $this->logger->log($payment, $result);
        return $result;
    }
}

// Nutzung
$service = new PaymentService(
    new StripeProcessor(),
    new DatabaseLogger()
);
💡 Praktischer Tipp: SOLID-Prinzipien sind Richtlinien, keine Gesetze. Wenden Sie sie an, wo sie Sinn ergeben. Übertriebene Anwendung führt zu Over-Engineering. Beginnen Sie einfach und refaktorisieren Sie, wenn Komplexität wächst.

Weitere Informationen

Texterstellung mit KI-Unterstützung

Enjix Beta

Enjyn AI Agent

Hallo 👋 Ich bin Enjix — wie kann ich dir helfen?
LLMs können Fehler machen. Ihre Nachrichten werden an Google Gemini weitergeleitet.
120