Intent
The strategy pattern is a family of algorithms, each one encapsualted and by that interchangeable to the receivers (Gamma, Helm, Johnson & Vlissides, 1994, p. 315; Shvets, n.d.).
Structure
The strategy interface defining the algorithms, a context calling the algorithms of that interface implemented by a concrete strategy.
Object Oriented Way
A Client
instantiates a ConcreteStrategy
and passes it to the Context
.
The Context
is receving any Strategy
that fulfills the interface.
class Client {
run() {
const strategy = new ConcreteStrategy();
const ctx = new Context();
ctx.strategy = strategy;
}
}
Declarative Way
It’s similar on a pure declarative way, where an interface describes the
arguments to take on a component level. The client invokes a component and
passes in another component (the ConcreteStrategy
) to fulfill the contract of
arguments. To demonstrate this, typescript helps a lot:
The ToggleLabelComponent
is the default concrete strategy, implements and
provies the ToggleLabelArgs
strategy interface. The FancyLabelComponent
implements the same interface for the args
and by that, makes the default
label interchangeable. Here is how to invoke it:
<Toggle @labelComponent={{component "fancy-label"}} />
For components we usually provide a decent default, that’s why this component
can be used without a passed in but provides this option. More
on this example can be found in the composable component type.
Combination of Both Ways
Combining the object oriented and declarative way can extend the usefulness of this pattern. Instead of passing in a component as another strategy, swapping in a javascript object containing algorithms for business logic. This way, UI and business logic/flows can be separated and be interchangeable.