Compare
Symptom
Human

A family of algorithms varies along one dimension (cost formula, sorting key, cipher, retry policy) and lives as if/else branches inside a host class. Adding a new algorithm means editing the host; algorithms cannot be tested in isolation; the host accumulates algorithm-specific magic numbers.

Agent

Algorithm-specific code lives inside a host class with type-tag dispatch the agent must read to understand variant behaviour. Adding an algorithm requires the agent to edit the host; the diff blast radius is unpredictable; per-algorithm tests require constructing the host's full graph.

Goal
Human

Each algorithm is a small class implementing one operation method; the host holds a strategy reference and delegates. Algorithms are interchangeable at the construction site; new algorithms are new classes; the host stays unchanged.

Agent

One strategy interface and N small implementations the agent reads independently. Per-algorithm verification is one-file-scoped; strategy selection is one expression at the construction site; the host's relevant method is a one-line delegation.

Before the pattern

class Order {
constructor(shippingType) {
this.shippingType = shippingType;
}
shippingCost(weight, distance) {
if (this.shippingType === 'standard') {
return weight * 0.5 + distance * 0.01;
} else if (this.shippingType === 'express') {
return weight * 1.0 + distance * 0.02 + 5;
} else if (this.shippingType === 'overnight') {
return weight * 2.0 + distance * 0.05 + 15;
}
throw new Error(`unknown shippingType: ${this.shippingType}`);
}
}
// Adding 'two-day' or 'international' = a new branch.
// Testing one algorithm requires constructing a full Order.

After the pattern

class StandardShipping {
calculate(weight, distance) {
return weight * 0.5 + distance * 0.01;
}
}
class ExpressShipping {
calculate(weight, distance) {
return weight * 1.0 + distance * 0.02 + 5;
}
}
class OvernightShipping {
calculate(weight, distance) {
return weight * 2.0 + distance * 0.05 + 15;
}
}
class Order {
constructor(shippingStrategy) {
this.shippingStrategy = shippingStrategy;
}
shippingCost(weight, distance) {
return this.shippingStrategy.calculate(weight, distance);
}
}
const order = new Order(new ExpressShipping());
const cost = order.shippingCost(5, 200);
Example source: Illustrative example written for this site in the spirit of Design Patterns (Gamma, Helm, Johnson, Vlissides, Addison-Wesley, 1994), chapter 5. The book uses a Composition class with line-breaking strategies; this JavaScript adaptation uses shipping-cost algorithms to make the family-of-interchangeable-formulas shape concrete without overlapping with Kerievsky's loan-calculator example for the same pattern.
Pressure
Human

Algorithm dispatch inside the host is Repeated Switches at the worst level — every algorithm-related edit touches the host; every host edit risks affecting unrelated algorithms; tests of one algorithm require constructing the host's full collaborator set.

Agent

Type-tag dispatch inside the host forces every algorithm-related edit to load the full host file with all dispatch branches; the per-edit context covers the host plus the active branch instead of one strategy class. Tests for one algorithm pull in the host's collaborator graph, multiplying setup cost per per-algorithm verification.

Tradeoff
Human

Each strategy lives in its own file; the class count grows with algorithm count; client code must choose a strategy at construction time, pushing the type-tag decision out of the host but not out of the system. Strategy interfaces that grow optional methods drift toward Template Method or a god interface.

Agent

N strategy classes is N files the agent navigates per algorithm-related task. Strategy interface design matters — extra optional methods bloat every implementation and force per-implementation no-op tests the agent must verify.

Relief
Human

Algorithms are unit-testable in isolation with synthetic inputs; new algorithms are PR-sized; the host's shippingCost reads as a one-line delegation. Pricing tweaks, formula corrections, and A/B-testing variants all stay scoped to one strategy file.

Agent

Each strategy lives at one file the agent reads in isolation; adding a new algorithm is one new class implementing the strategy interface plus one construction-site edit, and the host class stays unchanged.

Trap
Human

Strategies that need shared state (rate tables, currency conversion, calibration constants) and pull them through constructor parameters of every strategy reintroduce duplication. Often a thin shared-context object (Strategy + Context-object pair) restores the focus; otherwise strategy interfaces drift toward god-interface territory.

Agent

Strategy interfaces with optional methods (some algorithms implement calibrate(), others do not) blur the contract. The agent must verify per-implementation interface completeness rather than reading the interface as a structural promise. Define one focused interface, or split the family by capability.