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!
}
}