Strategy Design Pattern

Strategy Design Pattern also known as a Policy design pattern comes under comes under Behavioural Design Pattern in Gang of Four Desgin Patterns. it allows choosing different algorithms or strategies as per requirement at run time.

Strategy Design Pattern allows choosing from multiple interchangeable algorithms at run time as per the requirement.

In order to add a new strategy, existing code doesn't need modification, but a new strategy can always be added hence following the Open/closed principle.

Some real-world example of Strategy Design Pattern

  • the Collections class provides a Collections.sort() method, it takes a sorting comparator at run time and sorts accordingly.
  • A Map application on mobile show the path from source to destination, based on the strategy at run time, such as walking, cycling, motorcycle, self-driving, or public transit, it chooses the best route.
  • A shop accepts payment via multiple strategies such as Cash, Credit/Debit Card, or Online Transaction, as per the requirement, the user can choose from any one of them.
  • A Calculator has to compute numbers, it has multiple strategies such as Addition, Subtraction, Multiplication, and Division, the strategy can be chosen at run time as per requirement.
package org.wesome.design.patterns;

public interface AppleCalculator {
    int calculate(int apple1, int apple2);
}
package org.wesome.design.patterns;

public class AddApple implements AppleCalculator {
    @Override
    public int calculate(int apple1, int apple2) {
        int sum = apple1 + apple2;
        System.out.println("adding " + apple1 + " apple and " + apple2 + " apple will be " + sum + " apple.");
        return sum;
    }
}
package org.wesome.design.patterns;

public class SubtractApple implements AppleCalculator {
    @Override
    public int calculate(int apple1, int apple2) {
        int subtract = apple1 - apple2;
        System.out.println("subtracting " + apple2 + " apple from " + apple1 + " apple will be " + subtract + " apple.");
        return subtract;
    }
}
package org.wesome.design.patterns;

public class MultiplyApple implements AppleCalculator {
    @Override
    public int calculate(int apple1, int apple2) {
        int multiply = apple1 * apple2;
        System.out.println("multiplying " + apple1 + " apple to " + apple2 + " apple will be " + multiply + " apple.");
        return multiply;
    }
}
package org.wesome.design.patterns;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class AppleContext {
    private final AppleCalculator appleCalculator;

    public int calculateApple(int apple1, int apple2) {
        return appleCalculator.calculate(apple1, apple2);
    }
}
package org.wesome.design.patterns;

public class Strategy {
    public static void main(String[] args) {
        AppleContext add = new AppleContext(new AddApple());
        add.calculateApple(10, 5);

        AppleContext subtract = new AppleContext(new SubtractApple());
        subtract.calculateApple(10, 5);

        AppleContext multiply = new AppleContext(new MultiplyApple());
        multiply.calculateApple(10, 5);
    }
}
package org.wesome.design.patterns;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class TemplateTest {
    @Test
    void testAdditionStrategy() {
        AppleContext add = new AppleContext(new AddApple());
        Assertions.assertEquals(15, add.calculateApple(10, 5));
    }

    @Test
    void testSubtractStrategy() {
        AppleContext subtract = new AppleContext(new SubtractApple());
        Assertions.assertEquals(5, subtract.calculateApple(10, 5));
    }

    @Test
    void testMultiplyStrategy() {
        AppleContext multiply = new AppleContext(new MultiplyApple());
        Assertions.assertEquals(50, multiply.calculateApple(10, 5));
    }
}
plugins {
    id 'java'
    id "io.freefair.lombok" version "6.2.0"
}

group = 'org.wesome'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = JavaVersion.VERSION_1_8

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}
repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.junit.jupiter:junit-jupiter:5.6.2'
}

test {
    useJUnitPlatform()
}

follow us on