> For the complete documentation index, see [llms.txt](https://heronyang.gitbook.io/clean-up-your-spaghetti/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://heronyang.gitbook.io/clean-up-your-spaghetti/4_stand_on_giants/strategy_pattern.md).

# Strategy Pattern

## Problem

How to design for varying, but related, algorithms or policies? How to design for the ability to change these algorithms or policies?

## Solution

Define each algorithm/policy/strategy in a separate class, with a common interface.

**Example**

*Following image/code are from* [*Wikipedia*](https://en.wikipedia.org/wiki/Strategy_pattern)*.*

![](/files/-M4CTAFC0msqofd2RRPr)

```java
public interface IBrakeBehavior {
    public void brake();
}

public class BrakeWithABS implements IBrakeBehavior {
    public void brake() {
        System.out.println("Brake with ABS applied");
    }
}

public class Brake implements IBrakeBehavior {
    public void brake() {
        System.out.println("Simple Brake applied");
    }
}

/* Client which can use the algorithms above interchangeably */
public abstract class Car {
    protected IBrakeBehavior brakeBehavior;

    public void applyBrake() {
        brakeBehavior.brake();
    }

    public void setBrakeBehavior(IBrakeBehavior brakeType) {
        this.brakeBehavior = brakeType;
    }
}

/* Client 1 uses one algorithm (Brake) in the constructor */
public class Sedan extends Car {
    public Sedan() {
        this.brakeBehavior = new Brake();
    }
}

/* Client 2 uses another algorithm (BrakeWithABS) in the constructor */
public class SUV extends Car {
    public SUV() {
        this.brakeBehavior = new BrakeWithABS();
    }
}

/* Using the Car Example */
public class CarExample {
    public static void main(String[] args) {
        Car sedanCar = new Sedan();
        sedanCar.applyBrake();  // This will invoke class "Brake"

        Car suvCar = new SUV();
        suvCar.applyBrake();    // This will invoke class "BrakeWithABS"

        // set brake behavior dynamically
        suvCar.setBrakeBehavior( new Brake() );
        suvCar.applyBrake();    // This will invoke class "Brake"
    }
}
```
