DEV Community

Cover image for Understanding Strategy Pattern
Ahmed Raza Idrisi
Ahmed Raza Idrisi

Posted on

Understanding Strategy Pattern

  • Definition: Strategy Pattern lets you define a family of algorithms (strategies), put each into its own class, and make them interchangeable without changing the code that uses them.

๐Ÿ‘‰ Instead of using a big if-else or switch statement, you delegate the behavior to a strategy object.

Example (without Strategy Pattern โŒ bad way):

class DiscountCalculator {
    public function calculate($type, $amount) {
        if ($type === 'percentage') {
            return $amount * 0.9; // 10% discount
        } elseif ($type === 'fixed') {
            return $amount - 50; // flat 50 off
        } elseif ($type === 'bogo') {
            return $amount / 2; // Buy-one-get-one
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

โŒ Problems:

Hard to extend (add new discounts โ†’ modify code โ†’ violates OCP).

Unit testing individual discounts is messy.

Too many if/else.

Example (with Strategy Pattern โœ… good way):

// Strategy Interface
interface DiscountStrategy {
    public function applyDiscount(float $amount): float;
}

// Concrete Strategies
class PercentageDiscount implements DiscountStrategy {
    public function applyDiscount(float $amount): float {
        return $amount * 0.9; // 10% off
    }
}

class FixedDiscount implements DiscountStrategy {
    public function applyDiscount(float $amount): float {
        return $amount - 50; // flat 50 off
    }
}

class BogoDiscount implements DiscountStrategy {
    public function applyDiscount(float $amount): float {
        return $amount / 2; // buy one get one
    }
}

// Context (uses strategy)
class DiscountCalculator {
    private DiscountStrategy $strategy;

    public function __construct(DiscountStrategy $strategy) {
        $this->strategy = $strategy;
    }

    public function calculate(float $amount): float {
        return $this->strategy->applyDiscount($amount);
    }
}

Enter fullscreen mode Exit fullscreen mode
  • complete usage
$calculator = new DiscountCalculator(new PercentageDiscount());
echo $calculator->calculate(1000); // 900

$calculator = new DiscountCalculator(new FixedDiscount());
echo $calculator->calculate(1000); // 950

$calculator = new DiscountCalculator(new BogoDiscount());
echo $calculator->calculate(1000); // 500

Enter fullscreen mode Exit fullscreen mode

We already did that above ๐Ÿ‘† but hereโ€™s the beauty:

๐Ÿ‘‰ If tomorrow you want a FestivalDiscount, just add a new class:

class FestivalDiscount implements DiscountStrategy {
    public function applyDiscount(float $amount): float {
        return $amount * 0.7; // 30% festival discount
    }
}

Enter fullscreen mode Exit fullscreen mode

No need to modify the existing code โ†’ just plug it in.
This shows Open-Closed Principle (OCP) + Strategy Pattern together.

Top comments (0)