A robust Low-Level Design (LLD) implementation of a Food Delivery System, focusing on scalability, maintainability, and clean code principles. This project demonstrates various design patterns and architectural layers used in modern backend systems.
The system is designed using a Layered Architecture to separate concerns and ensure high cohesion. Each layer has a specific responsibility, making the codebase easier to test and extend.
src/
├── modals/ # Data models/Entities (POJOs)
│ ├── User.java # Represents Customers/Delivery Partners
│ ├── Restaurant.java # Store details and menus
│ ├── Order.java # Core entity managing the transaction
│ ├── Item.java # Individual food items
│ ├── Menu.java # Collection of items for a restaurant
│ └── ... # Payment, Address, Role, etc.
├── state/ # State Pattern implementation
│ ├── OrderState.java # Enum defining all possible order states
│ └── OrderStateMachine.java # Logic for valid state transitions
├── strategy/ # Strategy Pattern implementation
│ ├── DeliveryAssignmentStrategy.java # Interface for partner assignment
│ └── NearestDeliveryPartnerStrategy.java # Concrete implementation
├── services/ # Business Logic Layer
│ ├── DeliveryPartnerService.java # Manages partner availability and assignment
│ └── PaymentService.java # Handles payment processing
├── repository/ # Data Access Layer
│ └── OrderRepository.java # In-memory storage for orders
└── exceptions/ # Custom Domain Exceptions
├── InvalidOrderStateException.java
└── PaymentFailedException.java
Used to manage the complex lifecycle of an Order. By decoupling state logic from the Order class, we avoid massive if-else blocks and ensure that state transitions follow strict rules.
- States:
CREATED,CONFIRMED_BY_RESTAURANT,PREPARING,OUT_FOR_DELIVERY,DELIVERED,CANCELLED. - Validator:
OrderStateMachineensures an order cannot go fromCREATEDdirectly toDELIVERED.
Used for Delivery Partner Assignment. The system can have multiple strategies for picking a delivery partner (e.g., Nearest, Top-Rated, Least Busy).
- Advantage: New strategies can be added without modifying the core delivery service.
classDiagram
class Order {
-String id
-String userId
-String restaurantId
-List~Item~ items
-OrderState state
+moveTo(OrderState next)
+totalPrice() double
}
class OrderStateMachine {
<<static>>
-EnumMap transitions
+validate(OrderState current, OrderState next)
}
class DeliveryAssignmentStrategy {
<<interface>>
+assign(Order order, List~DeliveryPartner~ partners) DeliveryPartner
}
class NearestDeliveryPartnerStrategy {
+assign(Order order, List~DeliveryPartner~ partners) DeliveryPartner
}
class Restaurant {
-String id
-String name
-Menu menu
-Address address
}
class DeliveryPartner {
-String id
-String name
-boolean isAvailable
+tryAssign() boolean
}
Order --> OrderState
Order ..> OrderStateMachine
DeliveryAssignmentStrategy <|-- NearestDeliveryPartnerStrategy
DeliveryPartnerService --> DeliveryAssignmentStrategy
Restaurant --> Menu
Menu "1" *-- "many" Item
Order "1" *-- "many" Item
- Thread-Safe State Transitions: The
Orderclass uses synchronized methods to ensure state changes are atomic. - Decoupled Assignment Logic: Delivery logic is abstracted behind a strategy interface.
- Robust Error Handling: Custom exceptions for domain-specific failures (e.g., invalid state transitions).
- Layered Separation: Clear distinction between data (modals), logic (services), and storage (repository).
- Java 11 or higher
- VS Code with Java Extension Pack
The entry point is src/App.java. Currently, it serves as a placeholder for integration tests.
# Compile and run (via VS Code or CLI)
javac -d bin src/**/*.java
java -cp bin App