Define a family of algorithms, encapsulate each one, and make them interchangeable.
The Problem
Multiple pricing models (percentage discount, flat discount, buy-one-get-one, volume-based tiers) are embedded in a single service with conditional logic. Adding a new pricing strategy requires modifying the existing service, violating the Open/Closed Principle.
The Solution
The Strategy pattern extracts each pricing algorithm into its own class implementing PricingStrategy. The PricingService holds a reference to the current strategy and delegates calculations. Strategies are interchangeable at runtime.
All strategies are decorated with @Injectable() and registered as providers. The PricingService receives all strategies via constructor injection and stores them in a map. The controller specifies the strategy name in the request, and the service selects and applies it. This leverages NestJS’s DI to manage strategy lifecycle.
When to Use
You have a family of related algorithms and want to switch between them at runtime.
You want to isolate the algorithm logic from the code that uses it.
Multiple classes differ only in their behavior — Strategy lets you extract the varying behavior.
You want to eliminate conditional statements for selecting behaviors.
When NOT to Use
You only have one or two algorithms that rarely change — the pattern adds unnecessary abstraction.
The algorithms share significant state with the context, making separation awkward.