DEV Community

Cover image for SOLID Principles
Parzival
Parzival

Posted on

SOLID Principles

Understanding SOLID Principles in PHP

Single Responsibility Principle (SRP)

A class should have only one reason to change.

// Bad
class User {
    public function saveUser($data) { /* ... */ }
    public function generateReport() { /* ... */ }
    public function sendEmail() { /* ... */ }
}

// Good
class User {
    public function save($data) { /* ... */ }
}

class UserReportGenerator {
    public function generate() { /* ... */ }
}

class UserNotifier {
    public function sendEmail() { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode

Open/Closed Principle (OCP)

Software entities should be open for extension but closed for modification.

// Bad
class PaymentProcessor {
    public function processPayment($type) {
        if ($type === 'credit') {
            // Process credit payment
        } elseif ($type === 'debit') {
            // Process debit payment
        }
    }
}

// Good
interface PaymentMethod {
    public function processPayment();
}

class CreditPayment implements PaymentMethod {
    public function processPayment() { /* ... */ }
}

class DebitPayment implements PaymentMethod {
    public function processPayment() { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode

Liskov Substitution Principle (LSP)

Subtypes must be substitutable for their base types.

// Bad
class Bird {
    public function fly() { /* ... */ }
}

class Penguin extends Bird {
    public function fly() {
        throw new Exception("Cannot fly");
    }
}

// Good
interface Flyable {
    public function fly();
}

class Bird {
    public function eat() { /* ... */ }
}

class Sparrow extends Bird implements Flyable {
    public function fly() { /* ... */ }
}

class Penguin extends Bird {
    public function swim() { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode

Interface Segregation Principle (ISP)

Clients should not be forced to depend on interfaces they don't use.

// Bad
interface Worker {
    public function work();
    public function eat();
    public function sleep();
}

// Good
interface Workable {
    public function work();
}

interface Eatable {
    public function eat();
}

interface Sleepable {
    public function sleep();
}

class Human implements Workable, Eatable, Sleepable {
    public function work() { /* ... */ }
    public function eat() { /* ... */ }
    public function sleep() { /* ... */ }
}

class Robot implements Workable {
    public function work() { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode

Dependency Inversion Principle (DIP)

High-level modules should not depend on low-level modules. Both should depend on abstractions.

// Bad
class UserService {
    private MySQLDatabase $database;

    public function __construct() {
        $this->database = new MySQLDatabase();
    }
}

// Good
interface DatabaseInterface {
    public function query($sql);
}

class UserService {
    private DatabaseInterface $database;

    public function __construct(DatabaseInterface $database) {
        $this->database = $database;
    }
}

class MySQLDatabase implements DatabaseInterface {
    public function query($sql) { /* ... */ }
}

class PostgreSQLDatabase implements DatabaseInterface {
    public function query($sql) { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode

These principles help create maintainable, flexible, and robust code. Following SOLID makes your code easier to test, modify, and extend over time.

Top comments (0)