Strategy Design Pattern

 


If you have multiple conditions (equivalent to multiple if-else statements) within a switch statement and you want to refactor them using the strategy pattern, you can create a strategy for each condition. Let's use an example of a system that calculates shipping costs based on the destination and weight of a package.

public class ShippingCalculator { public double calculateShippingCost(String destination, double weight) { double cost; switch (destination) { case "Local": if (weight <= 5) { cost = 5.0; } else { cost = 8.0; } break; case "Domestic": if (weight <= 5) { cost = 10.0; } else { cost = 15.0; } break; case "International": if (weight <= 5) { cost = 20.0; } else { cost = 30.0; } break; default: throw new IllegalArgumentException("Invalid destination: " + destination); } return cost; } }

Refactored Code using Strategy Pattern:


Step 1: Define the ShippingStrategy Interface


public interface ShippingStrategy { double calculateShippingCost(double weight); }





Step 2: Create Concrete Strategy Classes


public class LocalShippingStrategy implements ShippingStrategy { @Override public double calculateShippingCost(double weight) { return (weight <= 5) ? 5.0 : 8.0; } } public class DomesticShippingStrategy implements ShippingStrategy { @Override public double calculateShippingCost(double weight) { return (weight <= 5) ? 10.0 : 15.0; } } public class InternationalShippingStrategy implements ShippingStrategy { @Override public double calculateShippingCost(double weight) { return (weight <= 5) ? 20.0 : 30.0; } }

Step 3: Modify the ShippingCalculator to Use Strategy.

public class ShippingCalculator { private ShippingStrategy shippingStrategy; public ShippingCalculator(ShippingStrategy shippingStrategy) { this.shippingStrategy = shippingStrategy; } public void setShippingStrategy(ShippingStrategy shippingStrategy) { this.shippingStrategy = shippingStrategy; } public double calculateShippingCost(double weight) { return shippingStrategy.calculateShippingCost(weight); } }

Step 4: Usage


public class Main { public static void main(String[] args) { ShippingCalculator shippingCalculator = new ShippingCalculator(new LocalShippingStrategy()); double cost = shippingCalculator.calculateShippingCost(3.0); System.out.println("Shipping cost: $" + cost); // Change the strategy dynamically shippingCalculator.setShippingStrategy(new DomesticShippingStrategy()); cost = shippingCalculator.calculateShippingCost(7.0); System.out.println("Shipping cost: $" + cost); // You can easily add new shipping strategies without modifying the ShippingCalculator class } }

In this example, the ShippingCalculator initially uses a switch statement with multiple conditions. The refactored code introduces a ShippingStrategy interface and concrete strategy classes (LocalShippingStrategy, DomesticShippingStrategy, InternationalShippingStrategy). The ShippingCalculator class is modified to use the strategy pattern, allowing you to switch between shipping strategies dynamically without modifying the ShippingCalculator class. This approach makes the code more modular, extensible, and easier to maintain.




















Comments

Popular posts from this blog

Proxy Design Pattern Using Spring AOP

Use cases of Supplier in java 8