Back to LLD explorer
Transactional / OOD• Patterns: Strategy, Observer, Command

Inventory System

Hard

Problem Summary

Design a Distributed Multi-Warehouse Inventory System managing SKU stock allocation, soft holds during checkout, hard deductions upon fulfillment, and automated restock orders.

Functional Scope

  • Manage real-time inventory levels across multiple geographic warehouses.
  • Soft reservations: hold item for 15 minutes during checkout; release if unpaid.
  • Hard deduction on payment completion; replenishment alerts when safety thresholds breach.
  • Pluggable allocation strategy (Nearest warehouse, FIFO, Lowest shipping fee).
  • Thread-safe atomic updates to prevent overselling during flash sales.

Entity-Relationship (ER) Schema

WarehouseManager [1] --> [*] Warehouse
Warehouse [1] --> [*] StockItem
StockReservation [1] --> [1] StockItem
WarehouseManager [1] --> [1] AllocationStrategy

Design Approach

Apply a two-phase reservation protocol (soft reserve -> commit/release) to prevent flash sale overselling without incurring long-lived database locks.

Core Classes & Models

WarehouseManager (Orchestrator across regional warehouses)Warehouse (WarehouseId, location, stock map)StockItem (SKU, totalUnits, reservedUnits, threshold)AllocationStrategy (NearestWarehouseAllocation, BalancedLoadAllocation)StockAdjustmentCommand (Command pattern for restock and deduction auditing)
Code Blueprint
87 lines
/**
 * Low-Level Design: Inventory Management & Warehousing System
 * Design Patterns Applied:
 *  - Strategy Pattern: Stock replenishment threshold calculations (EOQ / Min-Max)
 *  - Observer Pattern: Real-time low-stock alerts to warehouse supplier webhooks
 *  - Command Pattern: Transactional order stock reservation with automatic rollback
 */

import java.util.*;

// --- [DESIGN PATTERN: Observer] Low-stock alert listener ---
interface StockAlertListener {
    void onStockDepleted(String sku, int currentQuantity);
}

class SupplierReorderWebhook implements StockAlertListener {
    @Override
    public void onStockDepleted(String sku, int currentQuantity) {
        System.out.printf("⚠️ [Webhook Alert] Low stock for SKU '%s'! Remaining: %d. Triggering purchase order!%n", 
                          sku, currentQuantity);
    }
}

// --- [DESIGN PATTERN: Command] Stock reservation command ---
interface StockCommand {
    boolean execute();
    void rollback();
}

class ReserveStockCommand implements StockCommand {
    private final Map<String, Integer> warehouse;
    private final String sku;
    private final int quantity;

    public ReserveStockCommand(Map<String, Integer> warehouse, String sku, int quantity) {
        this.warehouse = warehouse; this.sku = sku; this.quantity = quantity;
    }

    @Override
    public boolean execute() {
        int current = warehouse.getOrDefault(sku, 0);
        if (current < quantity) {
            System.out.println("❌ Insufficient inventory for " + sku);
            return false;
        }
        warehouse.put(sku, current - quantity);
        System.out.printf("📦 Reserved %d units of %s (remaining: %d)%n", quantity, sku, current - quantity);
        return true;
    }

    @Override
    public void rollback() {
        warehouse.put(sku, warehouse.getOrDefault(sku, 0) + quantity);
        System.out.println("↩️ Rolled back stock reservation for " + sku);
    }
}

class WarehouseManager {
    private final Map<String, Integer> inventory = new HashMap<>();
    private final List<StockAlertListener> alertListeners = new ArrayList<>();

    public void addListener(StockAlertListener l) { alertListeners.add(l); }
    public void setStock(String sku, int qty) { inventory.put(sku, qty); }

    public synchronized boolean processOrder(String sku, int qty) {
        StockCommand cmd = new ReserveStockCommand(inventory, sku, qty);
        if (cmd.execute()) {
            int remaining = inventory.get(sku);
            if (remaining < 5) {
                for (StockAlertListener l : alertListeners) l.onStockDepleted(sku, remaining);
            }
            return true;
        }
        return false;
    }
}

public class Main {
    public static void main(String[] args) {
        WarehouseManager wh = new WarehouseManager();
        wh.addListener(new SupplierReorderWebhook());
        wh.setStock("SKU-LAPTOP-X", 6);

        System.out.println("--- Processing Inventory Order ---");
        wh.processOrder("SKU-LAPTOP-X", 3); // Leaves 3 -> triggers low stock alert!
    }
}