Alright, let’s dive into how to build a real-time order tracking system, like what you see when you're waiting for that pizza. I'll walk you through the low-level design (LLD) and show you how to piece it together.
Think about it: when you order food, you want to know where it is, right? Is it still being prepped? Has it left the restaurant? Is the delivery guy stuck in traffic? This visibility keeps customers happy and reduces support calls. Plus, it helps the restaurant and delivery service run more efficiently.
Before we get into the nitty-gritty, let’s lay out the key components we'll need:
Let’s zoom in on each component and figure out how they’ll work together.
This is the heart of the system. It needs to:
Here’s a basic Java class:
javapublic class Order {
private String orderId;
private String customerId;
private String restaurantId;
private String deliveryAddress;
private OrderStatus status;
// Getters and setters
}
enum OrderStatus {
PENDING,
PREPARING,
OUT_FOR_DELIVERY,
DELIVERED
}
This service is all about tracking the location of the delivery driver. It needs to:
Here's a simplified version:
javapublic class LocationService {
private Map<String, Location> driverLocations = new ConcurrentHashMap<>();
public void updateLocation(String driverId, Location location) {
driverLocations.put(driverId, location);
}
public Location getLocation(String driverId) {
return driverLocations.get(driverId);
}
}
class Location {
double latitude;
double longitude;
}
This service is responsible for sending updates to the customer. It needs to:
Using the Factory Design Pattern could be beneficial here to handle different notification types:
javapublic interface NotificationSender {
void sendNotification(String message, String userId);
}
public class PushNotificationSender implements NotificationSender {
public void sendNotification(String message, String userId) {
// Code to send push notification
System.out.println("Sending push notification to user " + userId + ": " + message);
}
}
// Factory
public class NotificationSenderFactory {
public NotificationSender getSender(String type) {
if ("push".equalsIgnoreCase(type)) {
return new PushNotificationSender();
}
// Add other types like SMS, Email
return null;
}
}
This is where the magic happens. We need a way to push updates to the customer's app in real-time. Options include:
For this example, let’s use WebSockets. Here’s a basic setup:
java@ServerEndpoint("/orderUpdates/{orderId}")
public class OrderUpdateWebSocket {
private static Map < String, Session > sessions = new ConcurrentHashMap < > ();
@OnOpen
public void onOpen(Session session, @PathParam("orderId") String orderId) {
sessions.put(orderId, session);
System.out.println("Session opened for orderId: " + orderId);
}
@OnClose
public void onClose(Session session, @PathParam("orderId") String orderId) {
sessions.remove(orderId);
System.out.println("Session closed for orderId: " + orderId);
}
@OnError
public void onError(Session session, Throwable error) {
System.err.println("Error in session: " + error.getMessage());
}
public static void sendUpdate(String orderId, String message) {
Session session = sessions.get(orderId);
if (session != null && session.isOpen()) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
System.err.println("Error sending message: " + e.getMessage());
}
}
}
}
Here’s how the components interact:
To handle a large number of orders and drivers, consider:
Here’s a simplified UML diagram:
Q: How often should the driver's location be updated?
That depends on the desired accuracy and battery life. A good starting point is every 5-10 seconds.
Q: What if the WebSocket connection drops?
Implement a fallback mechanism, such as polling the server for updates or using Server-Sent Events (SSE).
Q: How can I test this system?
Use a combination of unit tests, integration tests, and end-to-end tests. Mock the external services to isolate the components.
Want to test your skills building systems like this? Coudo AI has problems that challenge you to design and code real-world features. Try out the movie ticket API challenge for a taste of similar system design complexities.
Building a real-time order tracking system involves a lot of moving parts, but breaking it down into smaller components makes it manageable. By focusing on the LLD of each component and how they interact, you can create a scalable and reliable system. And remember, practice makes perfect, so keep coding and keep learning!
By mastering the low-level design (LLD) of each component, you're one step closer to building a scalable and reliable real-time order tracking system.\n\n