Design Patterns - 1

Strategy Pattern

·

2 min read

Need : When we are using inheritance in our application, there comes a situation where our design in no longer scalable. Strategy Pattern helps us resolve this problem.

When we are using inheritance, if we observe that multiple child classes are having same code (in methods) and that feature is not present in parent.In this situation we can use Strategy pattern.

Consider a base class Vehicle with one feature that gives normal drive capability.

public class Vehicle {
    private void drive(){
        System.out.println("This is normal drive capabilitys");
    }
}

OffRoadVehicle, SportsVehicle, SedanVehicle are child classes of Vehicle.

SedanVehicle does not need any special capability of driving . It is happy with what Vehicle class is providing.

public class SedanVehicle extends  Vehicle{
}

SportsVehicle needs a special drive capability that has power steering. It will override drive method in parent class.

public class SportsVehicle extends Vehicle{

    @Override
    public void drive(){
        System.out.println("This is special drive method - Power mode");
    }

}

OffRoadVehicle also needs the same drive capability of power steering so it implement the same method.

public class OffRoadVehicle extends Vehicle{

    @Override
    public void drive(){
        System.out.println("This is special drive method - Power mode");
    }
}

If we observe carefully there is code duplication. Now image there are another 20 other capabilities and all three child classes are implementing the same features.

Now let's see how Strategy Pattern solves this problem.

We will create an interface DriveStrategy that creates a bluepriint for drive method.

public interface VehicleStrategy {

    public void drive();
}

Next we will create two strategies : NormalDriveStrategy and PowerSteeringDriveStrategy that will provide specific implementation to drive method.

public class NormalDriveStrategy implements  VehicleStrategy{
    @Override
    public void drive() {
        System.out.println(" This is normal drive strategy");
    }
}
public class PowerSteeringDriveCapability implements  VehicleStrategy{
    @Override
    public void drive() {
        System.out.println("This is special drive capability with 
        power steering");
    }
}

Now we will create a base class Vehicle and instead of tightly coupling a particular drive strategy we will provide a reference to drive strategy and use constructor injection to get specific implentation.

public class Vehicle {

    private final VehicleStrategy vehicleStrategy;

    //constructor injection
    public Vehicle(VehicleStrategy vehicleStrategy){
        this.vehicleStrategy = vehicleStrategy;
    }

    public void drive(){
        vehicleStrategy.drive();
    }
}

In child classes like SedanVehicle, OffroadVehicle and SportsVehicle that extend Vehicle we will pass exact drive capability that we want.

public class OffRoadVehicle extends Vehicle {

    public OffRoadVehicle(){
        super(new PowerSteeringDriveCapability());
    }
}
public class SedanVehicle extends Vehicle{
    public SedanVehicle(VehicleStrategy vehicleStrategy) {
        super(new NormalDriveStrategy());
    }
}

Credits - https://www.youtube.com/watch?v=u8DttUrXtEw&list=PL6W8uoQQ2c61X_9e6Net0WdYZidm7zooW

Code - https://github.com/neelchikhal14/java-design-patterns