Parking Lot LLD, API spec, DB schema
Anonymous User
1076

ParkingLot LLD.
Share feedback and suggestion
https://leetcode.com/discuss/interview-question/6003635/WayFair-Automated-Parking-Lot-Problem-Design/

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

import org.joda.time.DateTime;

enum VehicleType
{
    TWO_WHEELER,
    THREE_WHEELER,
    FOUR_WHEELER
}

enum ParkingSpotType{
    SMALL,
    MEDIUM,
    LARGE  
}
enum TicketStatus
{
    UNPAID,
    PAID
}
class Vehicle{
    int id;
    VehicleType vehicleType;
    
}
class ParkingSpot{
    int id;
    ParkingSpotType parkingSpotType;
    double hourlyRate;
    double minRate;
    boolean isAvailable;
    Vehicle vehicle;
    
    public void parkTheVehicle(Vehicle vehicle)
    {
        this.vehicle = vehicle;
        this.isAvailable = false;
    }
    
    public void removeVehicle()
    {
        this.vehicle = null;
        this.isAvailable = true;
    }
}
class DisplayBoard
{
    int id;
    int freeSpots;
    public void updateDisplayBoard()
    {
        
    }
}
abstract class ParkingSpotManager{
    List<ParkingSpot> parkingSpots;
    
    ParkingSpotManager(List<ParkingSpot> parkingSpots)
    {
        this.parkingSpots = parkingSpots;
    }
    
    public void addParkingSpot(ParkingSpot parkingSpot)
    {
        parkingSpots.add(parkingSpot);
    }
    public void removeParkingSpot(ParkingSpot parkingSpot){
        for(ParkingSpot ps : parkingSpots)
        {
            if(ps.id == parkingSpot.id)
            {
                parkingSpots.remove(ps);
            }
        }
    };
    public abstract ParkingSpot findParkingSpot();
    
    public void parkTheVehicle(Vehicle vehicle, ParkingSpot parkingSpot)
    {
        parkingSpot.parkTheVehicle(vehicle);
    }
    public void  removeTheVehicle( ParkingSpot parkingSpot)
    {
        parkingSpot.removeVehicle();
    }
    
}

class TwoWheelerParkingSpotManager extends ParkingSpotManager
{
    
    TwoWheelerParkingSpotManager(List<ParkingSpot> parkingSpots)
    {
        super(parkingSpots);
    }
    public ParkingSpot findParkingSpot()
    {
       return parkingSpots.get(0);
    }
    
    
}
class FourWheelerParkingSpotManager extends ParkingSpotManager
{
    
    FourWheelerParkingSpotManager(List<ParkingSpot> parkingSpots)
    {
        super(parkingSpots);
    }
    public ParkingSpot findParkingSpot()
    {
       return parkingSpots.get(0);
    }
    
    
}

class ParkingSpotFactory
{
    public ParkingSpotManager getParkingSpotManager(ParkingSpotType parkingSpotType)
    {
        switch (parkingSpotType) {
            case SMALL:
                return new TwoWheelerParkingSpotManager(new ArrayList<>());
            case LARGE:
                return new FourWheelerParkingSpotManager(new ArrayList<>());
            default:
                throw new IllegalArgumentException("unrecongnized parkingspottype");
        }
    }
}
// whats the best place for display board;
class Floor{
    Map<ParkingSpotType,ParkingSpotManager> parkingSpotManagerList;
    DisplayBoard displayBoard;
    ParkingSpotFactory parkingSpotFactory;
    
    Floor()
    {
        parkingSpotManagerList = new HashMap<>();
        parkingSpotFactory = new ParkingSpotFactory();
        setParkingSpotManager();
    }
    
    private void setParkingSpotManager()
    {
        for(ParkingSpotType parkingSpotType : ParkingSpotType.values())
        {
            parkingSpotManagerList.put(parkingSpotType, parkingSpotFactory.getParkingSpotManager(parkingSpotType));
        }
    }
    
    public ParkingSpotManager getParkingSpotManager(ParkingSpotType parkingSpotType)
    {
        return parkingSpotManagerList.get(parkingSpotType);
    }
    
}
class Ticket
{
    int id;
    Vehicle vehicle;
    ParkingSpot parkingSpot;
    DateTime entryTime;
    DateTime exitTime;
    double amount;
    TicketStatus ticketStatus;
    Ticket(Vehicle vehicle, ParkingSpot parkingSpot)
    {
        this.vehicle = vehicle;
        this.parkingSpot = parkingSpot;
        entryTime = new DateTime();
        this.ticketStatus = TicketStatus.UNPAID;
    }
    
    public double calculatePrice()
    {
        return  (new DateTime().getHourOfDay() - entryTime.getHourOfDay())*parkingSpot.hourlyRate;
    }
}
class EntryGate {
    int id;
    
    public Ticket generateTicket(Vehicle vehicle, ParkingSpot parkingSpot)
    {
        Ticket tick =new Ticket(vehicle, parkingSpot);
        return tick;
    }
}

interface CostCompute
{
    public double calculatePrice(Ticket ticket);
}
class HourlyCostCompute implements CostCompute
{
    public double calculatePrice(Ticket ticket)
    {
        return  (new DateTime().getHourOfDay() - ticket.entryTime.getHourOfDay())*ticket.parkingSpot.hourlyRate;
    }
}
class MinCostCompute implements CostCompute
{
    public double calculatePrice(Ticket ticket)
    {
        return  (new DateTime().getMinuteOfDay() - ticket.entryTime.getMinuteOfDay())*ticket.parkingSpot.minRate;
    }
}
class ExitGate {
    CostCompute compute;
    
    ExitGate(CostCompute compute)
    {
        this.compute = compute;
    }
    
    public Double calculatePrice(Ticket ticket)
    {
       return compute.calculatePrice(ticket);
    }
    
    public void payTheTicket(Ticket ticket)
    {
        double price = calculatePrice(ticket);
        ticket.amount = price;
    }
}
class ParkingLot{
    List<Floor> floors;
    EntryGate entrygate;
    ExitGate exitGate;
    DisplayBoard displayBoard;
    ParkingLot()
    {
        this.floors = new ArrayList<>();
        this.entrygate = new EntryGate();
        this.exitGate = new ExitGate( new HourlyCostCompute());
        displayBoard = new DisplayBoard();
    }
    
    ///getter and setter for floor
    public void addParkingSpot(int floorId, ParkingSpot pSpot)
    {
        Floor floor = floors.get(floorId);
        ParkingSpotManager parkingSpotManager = floor.getParkingSpotManager(pSpot.parkingSpotType);
        parkingSpotManager.addParkingSpot(pSpot);
        
    }
    
    public ParkingSpot getParkingSpot(int floorId, ParkingSpotType parkingSpotType)
    {
        Floor floor = floors.get(floorId);
        ParkingSpot parkingSpot = floor.getParkingSpotManager(parkingSpotType).findParkingSpot();
        return parkingSpot;
    }
    
    public void parkTheVehicle(Vehicle vehicle, ParkingSpot spot, int floorId)
    {
        Floor floor = floors.get(floorId);
        floor.getParkingSpotManager(spot.parkingSpotType).parkTheVehicle(vehicle, spot);
        entrygate.generateTicket(vehicle, spot);
        displayBoard.updateDisplayBoard();
    }
    
    public void removeTheVehicle(Ticket ticket, int floorId, int exitGateId)
    {
        exitGate.payTheTicket(ticket);
        Floor floor = floors.get(floorId);
        floor.getParkingSpotManager(ticket.parkingSpot.parkingSpotType).removeTheVehicle(ticket.parkingSpot);
        displayBoard.updateDisplayBoard();
    }
}


/*
API Spec

Get /parking/spot -> get parking spot input {SpotType, floorId} 
DELETE /parking/spot/:{id} -> removes parking spot
POST /parking/spot -> {ParkingSpot object} ->add parking spot
POST /parking/park -> park a vehicle
POST /parking/exit -> exit the vehicle
GET /parking/price -> price 
GET /parking/status:{id} ->retrieve the current status of parking spot
DB spec
Vehicle
vehicle_id, vehicle_type

ParkingSpot
parking_spot_id,spot_type, is_available,vehicle_id, floor_id


Floor
floor_id, JSON{spot_ids}
Ticket
ticket_id, vehicle_id, spot_id,entry_time,exit_time,amount, payment_id

Payment
payment_id,amount,payment_status

*/
Comments (2)