TechnologyZer
technologyzer.com

Chain of Responsibility design pattern

Chain of Responsibility design pattern is a behavioral pattern that promotes the idea of passing a request along a chain of handlers. In this pattern, each handler has the capability to either handle the request or pass it to the next handler in the chain. The primary goal of the Chain of Responsibility pattern is to decouple senders of requests from their receivers, enabling multiple objects to have a chance to handle the request without the sender needing to know the exact handler or the structure of the chain.

5 real world example of Chain of Responsibility design pattern

Exception Handling: Chain of Responsibility can be used to handle exceptions hierarchically, where each handler deals with specific types of exceptions.

Authentication System: Used to authenticate users through multiple steps or methods, such as password authentication, token authentication, and biometric authentication.

Approval Workflow: Implementing a workflow where a document or request needs to be approved by multiple authorities in a specific order.

Logging System: Logging messages of different severity levels (e.g., INFO, WARNING, ERROR) where each logger decides whether to handle the message or pass it to the next logger in the chain.

Inventory Management System: Handling orders for products in an inventory management system, where each handler checks availability and processes the order based on predefined criteria.

~:Code of Inventory Management System using Chain of Responsibility design pattern:~

public class Order {
    private String product;
    private int quantity;
    private String customerAddress;

    //getters & Setters

}

// Handler interface
interface OrderHandler {
    void setNextHandler(OrderHandler handler);
    void processOrder(Order order);
}

// Concrete handler 1: Product Availability Handler
public class ProductAvailabilityHandler implements OrderHandler{

    private OrderHandler nextHandler;

    @Override
    public void setNextHandler(OrderHandler handler) {
        this.nextHandler = handler;
    }

    public void processOrder(Order order) {
        if (order.getQuantity() <= getProductAvailability(order.getProduct())) {
            System.out.println("Product is available. Processing order...");
            // Process order logic here
            if (nextHandler != null) {
                nextHandler.processOrder(order);
            }
        } else {
            System.out.println("Product is out of stock. Order cannot be processed.");
        }
    }

    // Simulated method to get product availability
    private int getProductAvailability(String product) {
        // Implementation to fetch product availability from inventory
        return 100; // Example: 100 units available
    }
}

// Concrete handler 2: Pricing Handler
class PricingHandler implements OrderHandler {
    private OrderHandler nextHandler;

    public void setNextHandler(OrderHandler handler) {
        this.nextHandler = handler;
    }

    public void processOrder(Order order) {
        double totalPrice = order.getQuantity() * getProductPrice(order.getProduct());
        System.out.println("Total price for the order: ₹" + totalPrice);
        // Pricing logic here

        if (nextHandler != null) {
            nextHandler.processOrder(order);
        }
    }

    // Simulated method to get product price
    private double getProductPrice(String product) {
        // Implementation to fetch product price from database or elsewhere
        return 50.0; // Example: ₹50 per unit
    }
}

// Concrete handler 3: Shipping Handler
class ShippingHandler implements OrderHandler {
    public void setNextHandler(OrderHandler handler) {
        // No next handler needed for shipping handler
    }

    public void processOrder(Order order) {
        System.out.println("Order shipped to customer: " + order.getCustomerAddress());
        // Shipping logic here
    }
}

// Client code
public class Main {
    public static void main(String[] args) {
        // Create order
        Order order = new Order();
        order.setProduct("Egg");
        order.setQuantity(150);
        order.setCustomerAddress("123 Road, City");

        // Create order handlers
        OrderHandler productAvailabilityHandler = new ProductAvailabilityHandler();
        OrderHandler pricingHandler = new PricingHandler();
        OrderHandler shippingHandler = new ShippingHandler();

        // Set up the chain
        productAvailabilityHandler.setNextHandler(pricingHandler);
        pricingHandler.setNextHandler(shippingHandler);

        // Process order
        productAvailabilityHandler.processOrder(order);
    }
}

Leave a Comment