The Strategy Pattern defines a family of algorithms, encapsulates each one into its own class, and makes them interchangeable at runtime. Instead of hardcoding behaviors into an object's DNA via inheritance, you give the object a "slot" and plug the behavior in via composition.

The Problems It Solves

When to Use It

Step-by-Step Implementation

Screenshot 2026-10-14 at 14.42.43.png

The image illustrates the architecture perfectly by splitting the behaviors into modular trees. FlyBehavior is an interface that all flying classes implement, meaning new flying classes just need to implement the fly() method. Similarly, QuackBehavior is an interface that just includes a quack() method that needs to be implemented.

1. Define the Interfaces

public interface FlyBehavior{
    void fly();
}
public interface QuackBehavior{
    void quack();
}

2. Create Concrete Strategies As shown in the diagram, FlyWithWings implements duck flying, while FlyNoWay provides the implementation for ducks that can't fly by doing nothing. The quack behaviors are split into Quack (quacks that really quack), Squeak (quacks that squeak, like a rubber duckie), and MuteQuack (quacks that make no sound at all).

public class FlyWithWings implements FlyBehavior{
    public void fly(){ System.out.println("Flying!"); }
}
public class FlyNoWay implements FlyBehavior{
    public void fly(){ // do nothing - can't fly!
    }
}

3. Build the Base Class (The Delegator)

The base class holds the interfaces, not the concrete classes.

public abstract class Duck{
    protected FlyBehavior flyBehavior;
    protected QuackBehavior quackBehavior;

    public void performFly(){ this.flyBehavior.fly(); }

    // Allows swapping at runtime
    public void setFlyBehavior(FlyBehavior fb){ this.flyBehavior = fb; }
}

4. Build the Client

The concrete duck wires up its initial state in the constructor.