My Solution for Design a Parking Lot with Score: 6/10

by yield_radiant616

Requirements


System users:

1- Parking owner

2- Client


1- Parking owner functionalities:

  • Add new spot to the parking with the main information like spot size and the fees pair hour
  • Remove or update spot information
  • get total fees for all transactions


2- Client

  • Check spot availability and check the spot size if it can fit with the car size
  • Reserve a new spot
  • Release the reservation and see the total fees depending on the parking time
class Car{ private final int ID; private float size; private string model; private string ownerName; public Car( float size, String model, String ownerName); public getters(); public setters(); }


class Spot{ private final int ID; private float size; private float feesPerHour; private int floorNumber; private boolean available; public Spot(float size, float feesPerHour, int floorNumber); public boolean isAvailable(float carSize); public getters(); public setters(); }


class BookingSpot{ private final int ID; private Spot spot; private Car car; private Date startTime; private Date endTime; private float totalFees; public BookingSpot(Car car, Spot spot); public void releaseReservation(); public float getTotalFees(); public getters(); public setters(); }



class Parking { private Map<Integer, Spot>spots; private List<BookingSpot>bookings; private static float totalProfit = 0; public void addNewSpot(Spot spot); public void removeSpot(int spotId); public void addNewBooking(Spot spot, Car car); public void releaseBooking(int bookingId); public static void getTotalOwnerProfit(); public Collection<Spot> getAllSpots(); public static Parking getInstance(); }

Analyze Relationships

  1. Composition relationship between Parking and Spot because Parking has an all spots
  2. Aggregation relationship between parking and Booking-Spot
  3. Association relationship between Booking-Spot and Car because Booking-Spot
  4. Association relationship between Booking-Spot and Spot



Establish Hierarchy

  • The Parking Lot system Doesn't need any type of inheritance or polymorphism




Design Patterns

  • Singleton design pattern in a Parking class



Define Class Members (write code)


public class Car { private final int ID; private float size; private String model; private String ownerName; public Car( float size, String model, String ownerName){ this.ID = new Random().nextInt(100000); this.size = size; this.model = model; this.ownerName = ownerName; } public int getID(){ return this.ID; } public float getSize(){ return this.size; } public String getModel(){ return this.model; } public String getOwnerName() { return ownerName; } public void setModel(String model) { this.model = model; } public void setOwnerName(String ownerName) { this.ownerName = ownerName; } public void setSize(float size) { this.size = size; } } public class Spot { private final int ID; private float size; private float feesPerHour; private int floorNumber; private boolean available; public Spot(float size, float feesPerHour, int floorNumber){ this.ID = new Random().nextInt(100000); this.floorNumber = floorNumber; this.size = size; this.feesPerHour = feesPerHour; this.available = true; } public boolean isAvailable(float carSize){ if(!this.available) throw new IllegalArgumentException("The spot is booked now"); if(this.size < carSize) throw new IllegalArgumentException("The car size is bigger than spot size"); return true; } public int getID() { return ID; } public float getSize() { return size; } public float getFeesPerHour() { return feesPerHour; } public int getFloorNumber() { return floorNumber; } public void setSize(float size) { this.size = size; } public void changeSpotStatus(boolean status) { this.available = status; } public void setFeesPerHour(float feesPerHour) { this.feesPerHour = feesPerHour; } public void setFloorNumber(int floorNumber) { this.floorNumber = floorNumber; } } public class BookingSpot { private final int ID; private final Car car; private final Spot spot; private final LocalTime startTime; private LocalTime endTime; private float totalFees; public BookingSpot(Car car, Spot spot){ this.ID = new Random().nextInt(100000); this.car = car; this.spot = spot; this.startTime = LocalTime.now(); } public void releaseReservation(){ this.endTime = LocalTime.now(); Duration duration = Duration.between(this.startTime, this.endTime); long hours = duration.toHours(); totalFees = hours * spot.getFeesPerHour(); spot.changeSpotStatus(true); } public float getTotalFees(){ return this.totalFees; } public Car getCar() { return car; } public Spot getSpot() { return spot; } public LocalTime getStartTime() { return startTime; } public LocalTime getEndTime() { return endTime; } public int getID() { return ID; } } public class Parking { private final Map<Integer, Spot> spots = new HashMap<>(); private final Map<Integer, BookingSpot> bookings = new HashMap<>(); private static Parking parking; private static float totalProfit = 0; public static Parking getInstance(){ if(parking == null){ parking = new Parking(); } return parking; } public void addNewSpot(Spot spot){ spots.put(spot.getID(), spot); } public void removeSpot(int spotId){ spots.remove(spotId); } public void addNewBooking(Spot spot, Car car){ if(spot.isAvailable(car.getSize())){ spot.changeSpotStatus(false); BookingSpot bookingSpot = new BookingSpot(car, spot); bookings.put(bookingSpot.getID(), bookingSpot); } } public void releaseBooking(int bookingId){ BookingSpot bookingSpot = bookings.get(bookingId); bookingSpot.releaseReservation(); totalProfit += bookingSpot.getTotalFees(); System.out.println("Total fees is: " + bookingSpot.getTotalFees()); } public static void getTotalOwnerProfit(){ System.out.println("Total profits is: " + totalProfit); } public Collection<Spot> getAllSpots() { return spots.values(); } }

Adhere to SOLID Guidelines

Check and explain whether your design adheres to solid principles (Ask interviewer what SOLID principle is if you can not recall it.)...


1- Each class responsible for single task

2- the system is open for extension but close to modified

Consider Scalability and Flexibility

Explain how your design can handle changes in scale and whether it would be easily to extend with new functionalities...





Create/Explain your diagram(s)

Try creating a class, flow, state and/or sequence diagram using the diagramming tool. Mermaid flow diagrams can be used to represent system use cases. You can ask the interviewer bot to create a starter diagram if unfamiliar with the tool. Briefly explain your diagrams if necessary...





Future improvements

Critically examine your design for any flaws or areas for future improvement...