# Strategy and Functions as Strategies — Design Patterns

Source: https://www.skillbyai.com/en/design-patterns/b-strategy

> Interchangeable algorithms behind one interface.

## Pick the algorithm at runtime

**Intent:** define a family of algorithms, encapsulate each one, and make them interchangeable so the client can choose at runtime. Shipping cost rules, pricing and discount rules, sorting or ranking policies, retry back-off policies and compression formats are typical. Strategy replaces growing `if/else` or `switch` chains spread across a codebase with a single variation point. In languages with **first-class functions**, a strategy is usually just a function with a known signature, and a map of name to function replaces the class hierarchy; classes still make sense when a strategy holds configuration or several related methods. **Avoid it** for one algorithm with no realistic alternatives.

## Swap, notify and encapsulate actions

Behavioural patterns organise how objects share work and communicate.

![Three ideas: interchangeable algorithms, event notification, actions as objects.](assets/figures/design-patterns/section-6-map.svg) — Figure 6.1 — Strategy, observer and command.

## Shipping cost strategies as functions

A typed function signature is the interface.

```typescript
type ShippingStrategy = (order: { weightKg: number; subtotalCents: number; country: string }) => number;

const flatRate: ShippingStrategy = () => 499;

const byWeight: ShippingStrategy = ({ weightKg }) => 299 + Math.ceil(weightKg) * 150;

const freeOverThreshold = (thresholdCents: number, fallback: ShippingStrategy): ShippingStrategy =>
  (order) => (order.subtotalCents >= thresholdCents ? 0 : fallback(order));

const strategies: Record<string, ShippingStrategy> = {
  standard: byWeight,
  flat: flatRate,
  promo: freeOverThreshold(5_000, byWeight),
};

function shippingCost(order: Order, method: string): number {
  const strategy = strategies[method];
  if (!strategy) throw new Error(`Unknown shipping method: ${method}`);
  return strategy(order);
}
```

## Strategy is everywhere in standard libraries

Passing a comparator to `Array.prototype.sort` or a `key` function to Python's `sorted` is the Strategy pattern in its lightest form.

**Quiz:** In TypeScript, what is often the simplest form of a Strategy?

- [ ] A deep inheritance hierarchy
- [ ] A Singleton class
- [x] A function with a known signature, chosen from a map
- [ ] A global mutable variable

*Answer:* A function with a known signature, chosen from a map. First-class functions replace many strategy classes.
