Technology Apr 25, 2026 · 3 min read

🚖 Designing an Uber/Ola-like Ride Booking System (LLD + UML Approach)

When I started practicing Low-Level Design, I realized that jumping directly into drawing UML diagrams often leads to messy, confusing designs. So instead, I followed a step-by-step approach—breaking the system into components, understanding flow, and then translating that into a clean UML. Here’s...

DE
DEV Community
by Srishti Prasad
🚖 Designing an Uber/Ola-like Ride Booking System (LLD + UML Approach)

When I started practicing Low-Level Design, I realized that jumping directly into drawing UML diagrams often leads to messy, confusing designs.

So instead, I followed a step-by-step approach—breaking the system into components, understanding flow, and then translating that into a clean UML.

Here’s how I approached designing a simplified Uber/Ola system.

🎯 Problem Statement

Design a ride-booking system that can:

Create a trip (source → destination)
Match a driver
Calculate price
Support extensibility (new pricing logic, ride types, etc.)

Step 1: Identify Core Components & Actors

Start simple. Who are the main actors?

Rider → requests a trip
Driver → fulfills the trip

These are the foundation of the system. Everything else builds around them.

Step 2: Define Features & Assumptions

To avoid overcomplicating early design, I made a few assumptions:

Each driver has one vehicle
One rider books one trip at a time
We focus only on trip creation flow

👉 This helps narrow scope and focus on correctness over completeness.

Step 3: Outline the Logical Flow (Client Perspective)

Instead of jumping into classes, I first defined the end-to-end flow from client side:

Rider enters source, destination, rideType
        ↓
RideBookingSystem receives request
        ↓
RideService orchestrates flow
        ↓
RideFactory → creates Bike / Auto / Cab
        ↓
StrategyMgr → selects pricing & matching strategy
        ↓
Driver is matched
        ↓
Price is calculated
        ↓
Trip is created

👉 This step is crucial—it directly drives your class design.

Step 4: Identify Classes & Responsibilities

Core Entities

Trip → represents a ride
Rider / Driver → system users
TripMetaData → context (ratings, locations)

Manager Classes (to organize logic)

TripMgr → manages trip lifecycle
RiderMgr / DriverMgr → manage users
StrategyMgr → selects strategies

👉 These act as centralized handlers for data and operations.

Step 5: Define Relationships

Understanding relationships is key to a good UML.

Aggregation (loosely coupled)
RiderMgr → Rider
DriverMgr → Driver

👉 These objects can exist independently.

Composition (tightly coupled)
TripMgr → Trip

👉 Trip lifecycle is controlled by TripMgr.

Step 6: Apply Design Patterns

To make the system extensible:

🔹 Singleton Pattern

Used for:

  • TripMgr
  • RiderMgr
  • DriverMgr

👉 Ensures a single source of truth as these classes will be interacting with database.

🔹 Strategy Pattern

Used for:

  • Pricing Strategy
  • Driver Matching Strategy
PricingStrategy → Default / RatingBased
DriverMatchingStrategy → LeastTimeBased

👉 This avoids hardcoding logic and allows easy extension.

🔹 Factory Pattern (Ride Selection)
To support multiple ride types:

RideFactory → BikeRide / AutoRide / CabRide

Flow:

  • User selects ride type
  • RideService delegates creation to RideFactory
  • Factory returns appropriate ride type object


👉 This centralizes ride creation and avoids scattered conditional logic.

Have attached a rough UML diagram for reference

This exercise helped me:

Think in terms of flow before code
Understand where Factory vs Strategy fits
Appreciate the importance of clear system boundaries

Still learning—would love to hear how others approach this problem 🙌

DE
Source

This article was originally published by DEV Community and written by Srishti Prasad.

Read original article on DEV Community
Back to Discover

Reading List