Understanding SOLID Design Principles in Laravel (For Beginners)

Author

Kritim Yantra

Feb 24, 2025

Understanding SOLID Design Principles in Laravel (For Beginners)

Understanding SOLID Design Principles in Laravel (For Beginners)

SOLID design principles are a set of guidelines that help developers write clean, maintainable, and scalable code. In this blog, we’ll break down each principle in simple terms and see how to apply them in Laravel with easy examples. Let’s dive in!


1. Single Responsibility Principle (SRP)

A class should have only one reason to change (i.e., do one thing).

Bad Example: A Laravel controller handling validation, business logic, and database operations.

class UserController extends Controller {
    public function store(Request $request) {
        // Validate
        $request->validate(['email' => 'required|email']);

        // Business logic
        $user = new User();
        $user->email = $request->email;
        $user->save();

        // Send welcome email
        Mail::to($user)->send(new WelcomeEmail());

        return redirect('/users');
    }
}

Good Example: Split responsibilities into dedicated classes.

  • Controller: Handles HTTP logic.
  • Form Request: Handles validation.
  • Service Class: Handles business logic.
// Step 1: Create a Form Request
class StoreUserRequest extends FormRequest {
    public function rules() {
        return ['email' => 'required|email'];
    }
}

// Step 2: Create a Service Class
class UserService {
    public function createUser(array $data): User {
        $user = User::create($data);
        Mail::to($user)->send(new WelcomeEmail());
        return $user;
    }
}

// Step 3: Simplified Controller
class UserController extends Controller {
    public function store(StoreUserRequest $request, UserService $service) {
        $service->createUser($request->validated());
        return redirect('/users');
    }
}

2. Open/Closed Principle (OCP)

Classes should be open for extension but closed for modification.

Bad Example: A payment processor that changes every time a new gateway is added.

class PaymentController extends Controller {
    public function pay(Request $request) {
        $gateway = $request->gateway;

        if ($gateway === 'stripe') {
            // Stripe logic
        } elseif ($gateway === 'paypal') {
            // PayPal logic
        }
    }
}

Good Example: Use an interface to allow new payment gateways without altering existing code.

interface PaymentGateway {
    public function pay(float $amount);
}

class StripeGateway implements PaymentGateway {
    public function pay(float $amount) { /* Stripe logic */ }
}

class PayPalGateway implements PaymentGateway {
    public function pay(float $amount) { /* PayPal logic */ }
}

class PaymentController extends Controller {
    public function pay(Request $request, PaymentGateway $gateway) {
        $gateway->pay($request->amount);
        return redirect('/success');
    }
}

3. Liskov Substitution Principle (LSP)

Subclasses should be substitutable for their parent classes without breaking the system.

Bad Example: A Bird class with a fly() method, but not all birds can fly.

class Bird {
    public function fly() { /* Fly logic */ }
}

class Duck extends Bird { } // Works

class Penguin extends Bird { } // Penguins can't fly! 🐧

Good Example (Laravel Context): Use interfaces to define specific behaviors.

interface Flyable {
    public function fly();
}

class Duck implements Flyable {
    public function fly() { /* Fly logic */ }
}

class Penguin { } // No fly() method here

4. Interface Segregation Principle (ISP)

Clients shouldn’t depend on interfaces they don’t use.

Bad Example: A bloated Worker interface forcing all classes to implement unnecessary methods.

interface Worker {
    public function work();
    public function sleep();
}

class Developer implements Worker {
    public function work() { /* Coding */ }
    public function sleep() { /* Not needed */ }
}

Good Example: Split interfaces into smaller, focused ones.

interface Workable {
    public function work();
}

interface Sleepable {
    public function sleep();
}

class Developer implements Workable {
    public function work() { /* Coding */ }
}

class Manager implements Workable, Sleepable {
    public function work() { /* Managing */ }
    public function sleep() { /* Sleeping */ }
}

5. Dependency Inversion Principle (DIP)

Depend on abstractions (interfaces), not concretions (classes).

Bad Example: Directly depending on a database class.

class MySQLDatabase {
    public function query() { /* MySQL logic */ }
}

class ReportService {
    private $database;

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

Good Example: Inject dependencies via interfaces.

interface Database {
    public function query();
}

class MySQLDatabase implements Database {
    public function query() { /* MySQL logic */ }
}

class CSVDatabase implements Database {
    public function query() { /* CSV logic */ }
}

class ReportService {
    private $database;

    public function __construct(Database $database) {
        $this->database = $database; // Loose coupling
    }
}

// Usage in Laravel (bind in AppServiceProvider):
$this->app->bind(Database::class, MySQLDatabase::class);

Why SOLID Matters in Laravel

  • Maintainability: Changes are isolated and predictable.
  • Testability: Easier to mock dependencies.
  • Scalability: New features can be added without breaking old code.

By following SOLID principles, your Laravel apps will become cleaner, more flexible, and easier to collaborate on. Happy coding! 🚀

LIVE MENTORSHIP ONLY 5 SPOTS

Laravel Mastery
Coaching Class Program

KritiMyantra

Transform from beginner to Laravel expert with our personalized Coaching Class starting June 23, 2025. Limited enrollment ensures focused attention.

Daily Sessions

1-hour personalized coaching

Real Projects

Build portfolio applications

Best Practices

Industry-standard techniques

Career Support

Interview prep & job guidance

Total Investment
$200
Duration
30 hours
1h/day

Enrollment Closes In

Days
Hours
Minutes
Seconds
Spots Available 5 of 10 remaining
Next cohort starts:
June 23, 2025

Join the Program

Complete your application to secure your spot

Application Submitted!

Thank you for your interest in our Laravel mentorship program. We'll contact you within 24 hours with next steps.

What happens next?

  • Confirmation email with program details
  • WhatsApp message from our team
  • Onboarding call to discuss your goals

Tags

Comments

Amar Chand

Amar Chand

Feb 28, 2025 09:12 PM

nice artical superb defiend. thanks
K

Kritim Yantra

May 30, 2025 09:20 AM

Thank you so much for your kind words! I’m really glad it helped in your learning. Keep exploring and all the best! 🚀

Please log in to post a comment:

Sign in with Google

Related Posts