Cab Booking System
Cab booking (Uber/Ola style) LLD covers riders, drivers, trips, location matching, fare calculation, and trip state — usually scoped to one city and in-process matching for inte…
Introduction
Cab booking (Uber/Ola style) LLD covers riders, drivers, trips, location matching, fare calculation, and trip state — usually scoped to one city and in-process matching for interviews.
Define Rider, Driver, Trip, LocationService, MatchingService, and FareCalculator. Trip states: Requested, Accepted, InProgress, Completed, Cancelled.
Extensions: surge pricing, ride pooling, rating.
Understanding the topic
Key concepts
- Driver: location, availability, vehicle type.
- Rider requests trip with pickup/drop.
- Matching: nearest available driver.
- Trip lifecycle state machine.
- Fare = base + distance + time + surge.
- Strategy for matching and pricing.
Step-by-step explanation
- Rider requests ride with endpoints.
- MatchingService finds nearby available driver.
- Driver accepts; trip becomes Accepted.
- Driver arrives; trip InProgress.
- Complete trip; calculate fare; charge rider.
- Driver becomes available again.
Informative example
Trip lifecycle with matching and fare calculation:
public record Location(double lat, double lng) {}public enum TripStatus { REQUESTED, ACCEPTED, IN_PROGRESS, COMPLETED, CANCELLED }public final class Driver {private final String id;private Location location;private boolean available = true;public Driver(String id, Location location) {this.id = id;this.location = location;}public boolean isAvailable() { return available; }public Location location() { return location; }public String id() { return id; }void assign() { available = false; }void release() { available = true; }}public final class Trip {private final String id;private final String riderId;private Driver driver;private TripStatus status = TripStatus.REQUESTED;private final Location pickup;private final Location drop;public Trip(String id, String riderId, Location pickup, Location drop) {this.id = id;this.riderId = riderId;this.pickup = pickup;this.drop = drop;}public void accept(Driver d) {if (status != TripStatus.REQUESTED) throw new IllegalStateException();driver = d;d.assign();status = TripStatus.ACCEPTED;}public void start() { status = TripStatus.IN_PROGRESS; }public void complete() {status = TripStatus.COMPLETED;driver.release();}public TripStatus status() { return status; }}public final class MatchingService {public Optional<Driver> nearest(List<Driver> drivers, Location pickup) {return drivers.stream().filter(Driver::isAvailable).min(Comparator.comparingDouble(d -> distance(d.location(), pickup)));}private double distance(Location a, Location b) {return Math.hypot(a.lat() - b.lat(), a.lng() - b.lng());}}
FareCalculator strategy uses distance(pickup, drop); TripRepository persists history.
Real-world use
Real-world applications
- Location-based matching LLD.
- State machine for trip lifecycle.
- Strategy for surge and vehicle types.
Best practices
- Trip owns status transitions with guards.
- MatchingService stateless; drivers updated on assign/release.
- LocationService interface for GPS updates.
- Fare breakdown transparent to rider receipt.
- Cancel rules per status (fee if after accept).
Common mistakes
- Driver available flag not reset after trip.
- Matching without considering already-assigned drivers.
- No trip id for rider tracking.
- Mixing HLD geo-sharding into LLD unnecessarily.
Advanced interview questions
Q1BeginnerCore cab booking classes?
Q2BeginnerTrip states?
Q3IntermediateNearest driver matching?
Q4IntermediateSurge pricing?
Q5AdvancedRide pooling LLD change?
Summary
Driver availability and location drive matching. Trip state machine controls lifecycle. MatchingService finds nearest available driver. Fare and surge via strategy pattern. Scope LLD; defer geo-sharding to HLD.