Refactoring Spaghetti into Elegance: Unraveling the Strategy Pattern
Photo by @jeshoots on Unsplash

Refactoring Spaghetti into Elegance: Unraveling the Strategy Pattern

In software development, design patterns provide structured solutions to common problems. The Strategy Pattern is one such solution, especially useful for organizing code. In this post, we'll explore the benefits of the Strategy Pattern and demonstrate how it can help in refactoring and making your code less prone to errors.

The scenario

Here @ Housemates Students can choose from various accommodation types: studio, ensuite, and luxury apartment. Additionally, they have the option to select amenities and decide their payment method: full payment or installments.

Here's a simplified version of what the code looked like initially:

class StudentAccommodation 

{

    public function book($type, $amenities, $paymentMethod) 

    {

        if ($type === 'studio') {

            // logic for booking studio

        } elseif ($type === 'ensuite') {

            // logic for booking ensuite

        } elseif ($type === 'luxury') {

            // logic for booking luxury apartment

        }

        if ($paymentMethod === 'full') {

            // logic for full payment

        } else {

            // logic for installments

        }

        // ... more code for amenities and other features

    }

}        

This approach, while functional, can quickly become a tangled mess as more features and conditions are added.

Enter the Strategy Pattern

The Strategy Pattern involves defining a family of algorithms, encapsulating each one, and making them interchangeable. This allows the algorithm to vary independently from clients that use it.

Let's refactor our Student Accommodation class using the Strategy Pattern:

First we will define our accommodation strategy:

// accommodation strategy contract

interface AccommodationStrategy {

    public function book();

}

class Studio implements AccommodationStrategy {

    public function book() {

        // logic for booking studio

    }

}

class Ensuite implements AccommodationStrategy {

    public function book() {

        // logic for booking ensuite

    }

}

class LuxuryApartment implements AccommodationStrategy {

    public function book() {

        // logic for booking luxury apartment

    }

}        

Then lets define our payment strategy:

// payment strategy contract

interface PaymentStrategy {

    public function pay();

}

class FullPayment implements PaymentStrategy {

    public function pay() {

        // logic for full payment

    }

}

class Installments implements PaymentStrategy {

    public function pay() {

        // logic for installments

    }

}        

With our strategies set, we can now create a context class responsible for students' bookings:

class StudentAccommodation

{

    private $accommodation;

    private $payment;

    public function __construct(

        AccommodationStrategy $accommodation,

        PaymentStrategy $payment

    ) {

        $this->accommodation = $accommodation;

        $this->payment = $payment;

    }

    public function book()

    {

        $this->accommodation->book();

        $this->payment->pay();

        // ... handle amenities and other features

    }

}        


Benefits of the Strategy Pattern

1. Separation of Concerns: Each strategy encapsulates a specific behaviour, making the code more modular.

2. Flexibility: New accommodation types or payment methods can be added without altering existing code.

3. Maintainability: Changes to a specific booking or payment logic only affect their respective strategy classes.

4. Reusability: Strategies can be reused across different parts of the application or even in different projects.

Conclusion

The Strategy Pattern is an invaluable asset for streamlining complex code. By segregating behaviours into distinct strategy classes, developers can foster a cleaner, more maintainable, and adaptable codebase. While I've showcased PHP in this example, the core concept is applicable across all programming languages.

To view or add a comment, sign in

Insights from the community

Others also viewed

Explore topics