Functional Scope (In-Scope)
- Rider/Driver Geo Proximity Matches: Find nearby available vehicles inside user-specified coordinates radius grids.
- Dynamic Pricing Models (Strategy Pattern): Implement surge factors or standard pricing calculated dynamically from supply/demand levels.
- Observer Trip Lifecycle Notifications: Publish live state changes to both Rider client apps and Driver terminals.
- Atomic Driver Status CAS flips: Flip driver availability flags atomically using compare-and-swap logic.
- Trip Lifecycle tracking: Manage ride workflows (Requested, Ongoing, Completed, Cancelled).
Explicit Boundaries (Out-of-Scope)
- No Real Physical GPS Map Rendering: Bypasses live Leaflet, Google Maps visual wrappers, or vector routing canvases.
- No Intelligent Shared Carpool Splits: Excludes complex multi-destination waypoint routing or rider-matching optimizations.
Clean reference designs detailing dynamic pricing and trip observers in Java and Python:
// ─── JAVA BLUEPRINT ──────────────────────────────────────────────────────────
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
enum DriverStatus { AVAILABLE, ON_TRIP, OFFLINE }
enum TripStatus { REQUESTED, ONGOING, COMPLETED, CANCELLED }
class Location {
private final double lat;
private final double lon;
public Location(double lat, double lon) {
this.lat = lat;
this.lon = lon;
}
public double getLat() { return lat; }
public double getLon() { return lon; }
public double distanceTo(Location other) {
return Math.sqrt(Math.pow(lat - other.getLat(), 2) + Math.pow(lon - other.getLon(), 2));
}
}
class Driver {
private final String id;
private final String name;
private final AtomicReference<DriverStatus> status = new AtomicReference<>(DriverStatus.AVAILABLE);
private volatile Location location;
public Driver(String id, String name, Location location) {
this.id = id;
this.name = name;
this.location = location;
}
public String getId() { return id; }
public String getName() { return name; }
public DriverStatus getStatus() { return status.get(); }
public Location getLocation() { return location; }
public void setLocation(Location location) { this.location = location; }
public boolean compareAndSetStatus(DriverStatus expected, DriverStatus update) {
return status.compareAndSet(expected, update);
}
}
interface TripObserver {
void onTripStatusChanged(String tripId, TripStatus newStatus);
}
class RiderNotifier implements TripObserver {
@Override
public void onTripStatusChanged(String tripId, TripStatus newStatus) {
System.out.println(String.format("[Rider App] Trip %s status updated: %s", tripId, newStatus));
}
}
class DriverNotifier implements TripObserver {
@Override
public void onTripStatusChanged(String tripId, TripStatus newStatus) {
System.out.println(String.format("[Driver Terminal] Trip %s alert: move to state %s", tripId, newStatus));
}
}
class Trip {
private final String id;
private final String riderId;
private final Driver driver;
private final Location pickup;
private final Location drop;
private final double fare;
private TripStatus status = TripStatus.REQUESTED;
private final List<TripObserver> observers = new CopyOnWriteArrayList<>();
public Trip(String id, String riderId, Driver driver, Location pickup, Location drop, double fare) {
this.id = id;
this.riderId = riderId;
this.driver = driver;
this.pickup = pickup;
this.drop = drop;
this.fare = fare;
}
public String getId() { return id; }
public Driver getDriver() { return driver; }
public TripStatus getStatus() { return status; }
public double getFare() { return fare; }
public void addObserver(TripObserver observer) { observers.add(observer); }
public synchronized boolean transitionTo(TripStatus next) {
// Enforce basic trip flow constraints
if (this.status == TripStatus.COMPLETED || this.status == TripStatus.CANCELLED) {
return false;
}
this.status = next;
notifyObservers(next);
return true;
}
private void notifyObservers(TripStatus next) {
for (TripObserver obs : observers) {
obs.onTripStatusChanged(id, next);
}
}
}
// ─── STRATEGY PATTERN (PRICING SYSTEM) ───────────────────────────────────────
interface PricingStrategy {
double calculateFare(Location start, Location end, int activeDemand, int availableDrivers);
}
class StandardPricingStrategy implements PricingStrategy {
@Override
public double calculateFare(Location start, Location end, int activeDemand, int availableDrivers) {
return start.distanceTo(end) * 10.0;
}
}
class SurgePricingStrategy implements PricingStrategy {
@Override
public double calculateFare(Location start, Location end, int activeDemand, int availableDrivers) {
double dist = start.distanceTo(end);
double multiplier = 1.0;
if (availableDrivers == 0 || ((double) activeDemand / availableDrivers) > 1.5) {
multiplier = 2.2;
}
return dist * 10.0 * multiplier;
}
}
class CabSharingService {
private final List<Driver> drivers = new CopyOnWriteArrayList<>();
private final Map<String, Trip> activeTrips = new ConcurrentHashMap<>();
private PricingStrategy pricingStrategy;
public CabSharingService(PricingStrategy strategy) {
this.pricingStrategy = strategy;
}
public void addDriver(Driver d) { drivers.add(d); }
public void setPricingStrategy(PricingStrategy strategy) { this.pricingStrategy = strategy; }
public int getAvailableDriversCount() {
int count = 0;
for (Driver d : drivers) {
if (d.getStatus() == DriverStatus.AVAILABLE) count++;
}
return count;
}
public Trip requestRide(String riderId, Location pickup, Location drop, int activeDemand) {
Driver bestDriver = null;
double minDistance = Double.MAX_VALUE;
for (Driver d : drivers) {
if (d.getStatus() == DriverStatus.AVAILABLE) {
double dist = d.getLocation().distanceTo(pickup);
if (dist < minDistance) {
minDistance = dist;
bestDriver = d;
}
}
}
if (bestDriver != null && bestDriver.compareAndSetStatus(DriverStatus.AVAILABLE, DriverStatus.ON_TRIP)) {
double fare = pricingStrategy.calculateFare(pickup, drop, activeDemand, getAvailableDriversCount() + 1);
String tripId = "TRIP-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
Trip trip = new Trip(tripId, riderId, bestDriver, pickup, drop, fare);
trip.addObserver(new RiderNotifier());
trip.addObserver(new DriverNotifier());
activeTrips.put(tripId, trip);
trip.transitionTo(TripStatus.ONGOING);
System.out.println(String.format("[Service] Rider %s matched with Driver %s. Fare: $%.2f",
riderId, bestDriver.getName(), fare));
return trip;
}
System.out.println("[Service] Ride Request Failed: No available drivers close to Rider: " + riderId);
return null;
}
public void completeTrip(String tripId) {
Trip trip = activeTrips.get(tripId);
if (trip != null && trip.transitionTo(TripStatus.COMPLETED)) {
trip.getDriver().compareAndSetStatus(DriverStatus.ON_TRIP, DriverStatus.AVAILABLE);
System.out.println("[Service] Trip " + tripId + " successfully completed.");
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
System.out.println("=== Cab Sharing Simulation ===");
CabSharingService service = new CabSharingService(new SurgePricingStrategy());
service.addDriver(new Driver("DRV-01", "Adam", new Location(1.0, 1.0)));
service.addDriver(new Driver("DRV-02", "Bella", new Location(2.0, 2.0)));
Location riderPickup = new Location(1.2, 1.2);
Location riderDrop = new Location(10.0, 10.0);
// High demand, low driver supply -> Surge applies
System.out.println("\n--- Requesting Ride under High Demand (Surge Mode) ---");
Trip trip1 = service.requestRide("RIDER-A", riderPickup, riderDrop, 8);
// Complete trip to return driver to availability pool
if (trip1 != null) {
service.completeTrip(trip1.getId());
}
System.out.println("\n--- Requesting Ride under Low Demand (Standard Mode) ---");
service.setPricingStrategy(new StandardPricingStrategy());
Trip trip2 = service.requestRide("RIDER-B", riderPickup, riderDrop, 1);
}
}