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

235 Dokumentationen verfügbar

Wissensdatenbank

SOLID Prinzipien Erklaert

Zuletzt aktualisiert: 20.01.2026 um 11:26 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

Enjix Beta

Enjyn AI Agent

Hallo 👋 Ich bin Enjix — wie kann ich dir helfen?
120