,

The Open Closed Principle (OCP) – Make Your Code Flexible! 🚀☕

open-closed-principle

Hey there, fellow coder! 👋 Today, we’re going to explore the Open-Closed Principle (OCP), one of the SOLID principles that help you write clean, maintainable, and scalable code.

Don’t worry—we’ll keep it super simple, with real-world examples and minimal Laravel/PHP code. Let’s dive in! 🏊‍♂️

What is the Open-Closed Principle? 🤔

The Open-Closed Principle says:

“Your code should be open for extension but closed for modification.”

What does that mean?

  • Open for extension → You can add new features without breaking things.
  • Closed for modification → You don’t change existing code to add those features.

Think of it like a smartphone 📱:

  • You can install new apps (extend functionality).
  • But you don’t rewrite the phone’s OS (no modification).

Bad Code Example: Payment Processor 💳 (Before OCP)

Let’s say you have a PaymentController in Laravel that handles two payment methods:

PHP
class PaymentController {
    public function pay($paymentType, $amount) {
        if ($paymentType == 'credit_card') {
            // Process credit card payment
            return "Charged $amount via Credit Card";
        } elseif ($paymentType == 'paypal') {
            // Process PayPal payment
            return "Charged $amount via PayPal";
        }
        throw new Exception("Payment method not supported.");
    }
}

The Problem 😬

  • What if you want to add StripeBank Transfer, or Crypto?
  • You keep modifying the same pay() method, adding more if-else blocks.
  • This violates OCP because you’re changing existing code instead of extending it.

The OCP-Friendly Solution 🎉

Instead of modifying the PaymentController, we’ll extend it! Here’s how:

Step 1: Define a Payment Interface (Contract)

PHP
interface PaymentMethod {
    public function pay($amount);
}

Step 2: Create Separate Payment Classes

PHP
class CreditCardPayment implements PaymentMethod {
    public function pay($amount) {
        return "Charged $amount via Credit Card";
    }
}

class PayPalPayment implements PaymentMethod {
    public function pay($amount) {
        return "Charged $amount via PayPal";
    }
}

// Later, you can add more without touching old code!
class StripePayment implements PaymentMethod {
    public function pay($amount) {
        return "Charged $amount via Stripe";
    }
}

Step 3: Refactor the PaymentController

PHP
class PaymentController {
    public function pay(PaymentMethod $paymentMethod, $amount) {
        return $paymentMethod->pay($amount);
    }
}

Now, Using It is Super Clean!

PHP
$paymentController = new PaymentController();

// Credit Card Payment
echo $paymentController->pay(new CreditCardPayment(), 100); 

// PayPal Payment
echo $paymentController->pay(new PayPalPayment(), 200); 

// Stripe Payment (added later, no changes to old code!)
echo $paymentController->pay(new StripePayment(), 300); 

Why This is Awesome? ✨

✅ No more if-else spaghetti – Each payment type has its own class.
✅ Easy to add new payments – Just create a new class (BitcoinPaymentBankTransfer, etc.).
✅ Zero changes to existing code – Follows OCP perfectly!


Real-World Example: Laravel Notifications 🔔

Laravel itself follows OCP! When you send notifications (email, SMS, Slack), you don’t modify Laravel’s core—you just extend it:

PHP
// Define a Notification
class InvoicePaid extends Notification {
    public function via($notifiable) {
        return ['mail', 'database']; // Extend channels easily!
    }
}

Want to add Slack later? Just update via()—no core changes needed!


Final Thoughts 🧠

The Open-Closed Principle keeps your code flexible and future-proof. Instead of hacking old code, extend it with new classes.

Remember:

🛑 Don’t modify – Avoid changing working code.
✅ Do extend – Add new features via interfaces & classes.

Now go refactor something! 🚀 Happy coding! 💻

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *