Design Example: Food Delivery System
A Food Delivery System (like UberEats or DoorDash) coordinates three primary actors: Customers, Restaurants, and Delivery Drivers.
Step 1: Requirements Gathering
Core Use Cases:
- Search: Customers can search for restaurants by cuisine, rating, or distance.
- Ordering: Add menu items to a cart and place an order.
- Restaurant Interface: Receive orders, update prep status, and mark as ready.
- Driver Interface: Accept delivery requests, pick up orders, and mark as delivered.
- Tracking: Customers can track the order status in real-time.
- Payment: Support for multiple payment gateways.
Order States:
- Status: PLACED, CONFIRMED, PREPARING, READY_FOR_PICKUP, IN_TRANSIT, DELIVERED, CANCELED.
Step 2: Identify Core Objects
- Order: Central record of the transaction and items.
- Account: User (Customer), RestaurantOwner, Driver.
- Restaurant: Contains menu, locations, and operating hours.
- Menu/Item: Hierarchical structure of food offerings.
- Delivery: Tracks driver assignment and GPS coordinates.
- Billing: Final invoice including delivery fees and tips.
Step 3: Design Class Diagram
Step 4: Implementation in TypeScript
enum OrderStatus { PLACED, PREPARING, READY, IN_TRANSIT, DELIVERED }
class MenuItem {
constructor(public id: string, public name: string, public price: number) {}
}
class Order {
private status: OrderStatus = OrderStatus.PLACED;
private items: MenuItem[] = [];
constructor(public id: string, public customerId: string, public restaurantId: string) {}
public updateStatus(newStatus: OrderStatus) {
this.status = newStatus;
this.notifyActors();
}
private notifyActors() {
// Notify Customer, Restaurant, and Driver based on status
}
}
class Restaurant {
private menu: MenuItem[] = [];
public acceptOrder(order: Order) {
console.log(`Restaurant accepted order ${order.id}`);
order.updateStatus(OrderStatus.PREPARING);
}
}Deep Dive: Observer Pattern for Order Tracking
In food delivery, the Observer Pattern is essential for status synchronization. The Order object acts as the subject, and the Customer App and Driver App are observers that react to status changes.
Wrap Up
Designing a Food Delivery system is a masterclass in Multi-Actor State Machines. Ensuring that a driver is matched to an order only after restaurant confirmation, and that the customer receives real-time updates, are the primary technical challenges in this LLD.
[!CAUTION] Always decouple the Payment from the Order Placement. The order should only be "confirmed" after a successful transaction from a 3rd party payment provider.