Strategy

Swap Algorithms at Runtime

Strategy puts each algorithm (shipping cost, discount, sorting rule) behind an interface. The context picks one at runtime. With lambdas, a strategy can be just a function — no class per algorithm needed.

Example

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, ShippingStrategy> strategies = new LinkedHashMap<>();
        strategies.put("standard", w -> 40 + 10 * w);
        strategies.put("express", w -> 99 + 20 * w);
        strategies.put("prime", w -> 0);
        strategies.put("bulk", new BulkShipping());

        double weightKg = 3;
        strategies.forEach((name, s) ->
                System.out.printf("%-9s Rs %.0f%n", name, s.cost(weightKg)));

        Checkout checkout = new Checkout(strategies.get("express"));
        System.out.println("Checkout total: Rs " + checkout.total(1500, weightKg));
    }
}

@FunctionalInterface
interface ShippingStrategy { double cost(double weightKg); }

class BulkShipping implements ShippingStrategy {
    public double cost(double w) { return w > 2 ? 5 * w : 60; }
}

class Checkout {
    private final ShippingStrategy shipping;
    Checkout(ShippingStrategy shipping) { this.shipping = shipping; }
    double total(double cart, double weight) { return cart + shipping.cost(weight); }
}

Output

standard  Rs 70
express   Rs 159
prime     Rs 0
bulk      Rs 15
Checkout total: Rs 1659.0

Strategy in Spring

public interface PaymentGateway { PaymentResult pay(Order order); String name(); }

@Component class RazorpayGateway implements PaymentGateway { ... public String name() { return "razorpay"; } }
@Component class PaytmGateway    implements PaymentGateway { ... public String name() { return "paytm"; } }

@Service
public class PaymentService {
    private final Map<String, PaymentGateway> gateways;
    // Spring injects every PaymentGateway bean; we index them by name
    public PaymentService(List<PaymentGateway> all) {
        this.gateways = all.stream().collect(Collectors.toMap(PaymentGateway::name, g -> g));
    }
    public PaymentResult pay(Order order, String gateway) {
        return gateways.get(gateway).pay(order);
    }
}