class ReservationService {

  public function calculateTotal()
  {
      return $this->pricingService
          ->applySeasonModifier()
          ->applyDiscountRules()
          ->applyChannelCommission()
          ->applyTaxes()
          ->buildInvoice();
  }

}

// Domain rules evolve
// architecture decisions matter
// complexity grows over time

Back to Comparison

A03 — Strategy + Polymorphism

Encapsulate behaviors through polymorphic strategy objects

Pattern: Strategy Pattern + Polymorphism

Philosophy: Encapsulate varying behaviors. Each strategy type implements its own pricing rules.

Description

A03 uses the Strategy Pattern to encapsulate different pricing behaviors. Each reservation type (Hotel, Event, etc.) has its own Strategy class implementing pricing logic. This makes the domain model more expressive and aligns code structure with business concepts.

Strengths:

  • Clear mapping between business types and code
  • Easy to test individual strategies in isolation
  • New reservation types require new strategy classes, not modifications
  • Good balance between structure and complexity
  • Controllers and services remain thin (30-32 lines)

Weaknesses:

  • More files (14) than simpler approaches
  • Phase04PricingStrategy duplicates logic from BasicPricingStrategy
  • Creating a new phase creates a new strategy duplicating prior logic
  • Needs better refactoring to handle shared behavior between strategies
  • Still requires understanding strategy hierarchy

Evolution Across Phases

Phase Files Lines of Code Controller (lines)
Phase 01 14 371 31
Phase 02 14 523 32
Phase 03 14 727 32
Phase 04 14 775 32

Strategy Duplication: Phase04PricingStrategy duplicates logic from BasicPricingStrategy to add 3 new methods. Shows the pattern works but needs refactoring for phase-based evolution.

Key Metrics

Total Files

14

Stable across phases

Total Lines of Code

775

+109% growth P01→P04

Controller Size (Phase 04)

32 lines

+1 line from Phase 01

Testability Score

Good

Strategies are testable units

Conclusion

Good balance with room for refinement.

A03 strikes a solid middle ground. Controllers stay thin, strategies are cohesive and testable, and the domain model clearly expresses business intent. However, it shows the risk of strategy duplication: adding a new phase requires copying prior strategy logic and extending it.

With better refactoring (composition over inheritance, shared trait methods), this pattern scales much better. It's an excellent choice when you have distinct product types with varying behaviors.

✓ When to Use A03

  • Product types or contexts have different calculation rules
  • Business domains map naturally to different strategies
  • You want good testability with clear behavior encapsulation
  • Teams benefit from seeing strategy-to-business mapping