Technical Blog

Strategy Design Pattern

The example of the Strategy Design Pattern.

img.png

When the child class inherits the parent class property then it is good. When the child class write its own property and two or more class has the same property then there is duplication of code.

This code is not reusable. There can be many method like speed limit, fuel capability, seat capability, display then we have to write for all the child classes.

When child override the method and other child also have the same method then there is code duplicate issue. This is solved by Strategy Design Pattern.

img.png

Previously all the functionality we were putting in the base class. Now we will not define in the base class. We will say that the Vehicle HAS - A drive interface

In the base class we just defined the DriveStrategy Object. The type of the drive strategy like normal or special that will be defined by the child class.

We created one constructor in the vehicle which will put the value to the object. This is Constructor Injection. The functionality will be given by the child class will be passed in the constructor. It will be assigned by the constructor.

In the drive method will only call obj.drive() this will call the drive method of the object.

Without the Strategy Pattern.

public class Vehicle {
    public void drive(){
        System.out.println("Normal Drive Functionality.");
    }
}
public class SportsVehicle extends Vehicle{
    @Override
    public void drive() {
        System.out.println("Special Functionality.");
    }
}
public class OffRoadVehicle extends Vehicle{
    @Override
    public void drive() {
        System.out.println("Special Functionality.");
    }
}
public class PassengerVehicle extends Vehicle{
}

Using the Strategy Pattern

In a strategy package, there is DriveStrategy, NormalDriveStrategy and SpecialDriveStrategy.

public interface DriveStrategy {
    void drive();
}
public class NormalDriveStrategy implements DriveStrategy{
    @Override
    public void drive() {
        System.out.println("Normal Drive Strategy.");
    }
}
public class SpecialDriveStrategy implements DriveStrategy{
    @Override
    public void drive() {
        System.out.println("Special Drive Strategy.");
    }
}

In the Vehicle class.

public class Vehicle {
    DriveStrategy driveObject;
    // Will not make like new NormalDriveStrategy. It is only the object of DriveStrategy.
    // When we have to add the interface then we add in the autowired.

    // Constructor Injection.
    Vehicle(DriveStrategy driveObj){
        this.driveObject = driveObj;
    }

    public void drive(){
        driveObject.drive();
        // It will call the drive method of the driveObject.
    }
}
public class PassengerVehicle extends Vehicle{
    PassengerVehicle(){
        super(new NormalDriveStrategy());
    }
}

super(new NormalDriveStrategy()) is calling the constructor of the superclass Vehicle and passing an instance of NormalDriveStrategy to it.

public class OffRoadVehicle extends Vehicle{
    OffRoadVehicle(){
        super(new SpecialDriveStrategy());
    }
}
public class SportsVehicle extends Vehicle{
    SportsVehicle() {
        super(new SpecialDriveStrategy());
    }
}

In the main class.

public class Main {
    public static void main(String[] args) {
        Vehicle vehicle = new SportsVehicle();
        vehicle.drive();
    }
}