Design Cab Booking (LLD)
1. Requirements
-
Functional
- Riders request trips with pickup and dropoff; system matches or assigns a driver vehicle.
- Track trip lifecycle: requested, assigned, in progress, completed, cancelled.
- Rider and driver both see trip state; fare estimate from distance and surge rules.
-
Non-Functional
- No double-assignment of one driver to concurrent active trips.
- Pluggable matching (nearest, highest rating) and pricing.
-
Assumptions / Out of Scope
- Maps routing is external; distances provided by stub or API.
2. Core Entities
| Entity | Responsibility | Key Attributes |
|---|---|---|
| Rider | Requests trips | identifier, location |
| Driver | Operates vehicle | identifier, vehicle, location, status |
| Trip | One ride instance | identifier, rider, driver, route, state |
| Vehicle | Capacity metadata | plate, model |
| FareEstimator | Price preview | base, perKm, surgeMultiplier |
| MatchingService | Pairs rider with driver | policy reference |
3. Class Diagram
Loading diagram…
4. State / Sequence Diagram (where relevant)
Loading diagram…
5. Design Patterns Applied
- Strategy — Matching and surge pricing policies. Strategy pattern.
- Observer — Trip state notifications to rider and driver apps. Observer pattern.
- State —
Tripstate machine. State pattern.
6. Implementation
Go
package cab
type Location struct {
Latitude, Longitude float64
}
type Trip struct {
Identifier string
RiderID string
DriverID string
State string
Pickup Location
Dropoff Location
}
type TripBookingService struct {
Matching MatchingService
Fare FareEstimator
}
func (service *TripBookingService) RequestTrip(riderID string, pickup, dropoff Location) (*Trip, error) { /* ... */ }JavaScript
class Trip {
constructor({ identifier, riderId, pickup, dropoff }) {
this.identifier = identifier;
this.riderId = riderId;
this.driverId = null;
this.state = 'requested';
this.pickup = pickup;
this.dropoff = dropoff;
}
}
class TripBookingService {
constructor({ matchingService, fareEstimator }) {
this.matchingService = matchingService;
this.fareEstimator = fareEstimator;
}
requestTrip({ riderId, pickup, dropoff }) { /* ... */ }
}7. Concurrency / Thread Safety
- Collisions: Two riders matched to same nearest driver; driver accepts overlapping trips.
- Granularity: Compare-and-set on driver status; transactional trip creation with row locks on driver pool.
- Go: Mutex per driver id during assignment; idempotent
RequestTripwith client token.
8. Extensibility & Followups
- Shared rides with multiple waypoints as composite trip graph.
- Driver earnings ledger and weekly payout export.
- Edge cases: rider cancel after assign, no-show fees, safety escalation flags.
Last updated on
Spotted something unclear or wrong on this page?