Skip to main content

Requirements for the Ride-Sharing System

Editorial

Functional Requirements

Let's define what our ride-sharing system needs to do. Each requirement is specific, testable, and will drive at least one design decision in our class diagram.

Rider Management:

  1. R1: A rider shall register with a name, email, phone number, and payment method. Each rider has a unique ID and a cumulative rating.
  2. R2: A rider shall request a ride by specifying a pickup location, destination, and ride type (Economy, Premium, XL).
  3. R3: A rider shall see an estimated fare before confirming the ride request. The estimate accounts for distance, duration, ride type, and current surge multiplier.
  4. R4: A rider shall be able to cancel a ride before the driver arrives at the pickup location. Cancellation after driver dispatch may incur a fee.

Driver Management:

  1. R5: A driver shall register with a name, license number, and associated vehicle. Each driver has a unique ID, a rating, and a current status (Available, Busy, Offline).
  2. R6: A driver shall toggle their availability (go online/offline). Only Available drivers are eligible for matching.
  3. R7: A driver shall accept or decline a ride request within a configurable timeout (default 30 seconds). Declining returns the request to the matching pool.
  4. R8: A driver shall update the ride status at key moments: confirm arrival at pickup, start the ride, complete the ride.

Vehicle and Ride Types:

  1. R9: The system shall support multiple vehicle types: Sedan, SUV, and Luxury. Each vehicle type maps to one or more ride types — Economy (Sedan), Premium (Luxury), XL (SUV).
  2. R10: A ride request shall only be matched with a driver whose vehicle is compatible with the requested ride type.

Ride Lifecycle:

  1. R11: A ride shall transition through defined states: Requested, Matched, DriverEnRoute, InProgress, Completed, Cancelled. Transitions follow strict rules — you cannot start a ride that hasn't been matched.
  2. R12: Upon ride completion, the system shall calculate the final fare based on actual distance and duration, apply the surge multiplier that was locked at request time, and deduct the platform commission.

Matching:

  1. R13: When a rider requests a ride, the system shall find the nearest available driver with a compatible vehicle within a configurable search radius (default 5 km).
  2. R14: If no driver is found within the radius, the request shall remain in Requested state for a configurable timeout before being automatically cancelled.

Pricing:

  1. R15: The system shall calculate fares using a formula: baseFare + (perKmRate * distance) + (perMinRate * duration), scaled by a surge multiplier and ride type rate card.
  2. R16: Surge pricing shall activate when the ratio of active ride requests to available drivers in a geographic zone exceeds a configurable threshold (e.g., 2:1). The multiplier scales with the ratio.

Ratings:

  1. R17: After ride completion, both rider and driver shall rate each other on a 1-5 scale. The cumulative rating is a running average of all received ratings.
  2. R18: A driver whose rating drops below a configurable threshold (e.g., 4.0) shall be flagged for review.

Non-Functional Requirements

Beyond functionality, our design must satisfy:

  1. Extensibility (Open/Closed Principle): Adding a new ride type (e.g., Pool, Bike) or a new matching algorithm (e.g., highest-rated driver) should not require modifying existing classes. Strategy Pattern enables this for matching and pricing.
  2. Loose Coupling: Riders and drivers should not depend on each other directly. The Ride object mediates their interaction, and the Observer Pattern decouples status notifications from ride state management.
  3. Single Responsibility: The RideService orchestrates the workflow but doesn't calculate fares (that's PricingStrategy) or find drivers (that's MatchingStrategy). Each class has one reason to change.
  4. Testability: Each component — matching, pricing, ride state transitions — must be testable in isolation. Strategy interfaces allow injecting mock algorithms in tests.
  5. Thread Awareness: Multiple riders may request rides simultaneously, and multiple drivers may go online/offline concurrently. While full thread safety is out of scope for this LLD, the design should not create inherent race conditions (e.g., assigning the same driver to two rides).

Scope Clarification

In Scope:

  • Rider and driver registration (simplified — no document verification)
  • Ride request, matching, lifecycle management, and completion
  • Fare estimation and calculation with surge pricing
  • Mutual rating system
  • Multiple ride types with vehicle compatibility
  • Driver availability toggling

Out of Scope:

  • Real GPS tracking or map integration — locations are (latitude, longitude) pairs with Euclidean distance for simplicity
  • Payment processing — we model PaymentMethod as an interface, not Stripe/PayPal integration
  • Ride pooling (shared rides with multiple riders) — this is a separate algorithmic challenge
  • Real-time push notification infrastructure — we model the Observer interface, not WebSocket implementation
  • Driver onboarding, background checks, or document uploads
  • Admin panel or analytics dashboards
  • Promo codes, referral bonuses, or tipping

Requirements-to-Design Traceability

Every requirement must map to at least one class or component. This traceability matrix ensures nothing is overlooked:

RequirementDrives Which Class/Component
R1 (Rider registration)Rider, Account
R2 (Request a ride)RideRequest, RideService, Location
R3 (Fare estimate)PricingStrategy, FareCalculator
R4 (Rider cancellation)Ride.cancel(), CancelledState
R5 (Driver registration)Driver, Vehicle
R6 (Driver availability)Driver.status, DriverStatus enum
R7 (Accept/decline)Driver.acceptRide(), matching timeout logic
R8 (Status updates)Ride.confirmArrival(), Ride.startRide(), Ride.completeRide()
R9-R10 (Vehicle types)VehicleType enum, RideType enum, compatibility map
R11 (Ride lifecycle)RideState interface + 6 concrete state classes
R12 (Final fare)FareCalculator, Ride.completedFare
R13-R14 (Matching)MatchingStrategy, NearestDriverStrategy
R15-R16 (Pricing/surge)PricingStrategy, SurgePricingStrategy, RateCard
R17-R18 (Ratings)Rating, Rider.rating, Driver.rating

Interview Tip

In a real interview, spend 3-5 minutes clarifying requirements before jumping into design. For a ride-sharing problem, key clarifying questions include:

  • "Should we support ride pooling (multiple riders in one car)?" — This massively changes the matching algorithm. For our scope: no.
  • "Do we model real-time GPS tracking or simplified locations?" — Real GPS adds infrastructure complexity. For LLD: simplified (lat/lng) coordinates.
  • "How does surge pricing work — per zone, per city, globally?" — This determines whether we need a geographic zone model. For our scope: per zone, with zones as simple identifiers.
  • "Can a rider have multiple active rides?" — Uber: no. This simplifies our model — one active ride per rider at a time.
  • "What happens if no driver is available?" — We need a timeout mechanism: the request stays open for N seconds, then auto-cancels.

Asking these questions shows the interviewer you think about edge cases and scope boundaries before over-engineering.