Requirements
The parking alot system will be used to manage vehicle parking across mutiple floors. The system will cater to different type of vehicles, including cars,bikes, and trucks, with varying parking spot sizes. The main functionalities of the system include:
Parking spot Assignment:
. The system should assign parking spots based on vehicle size and spot availability.
. It should manage spot reservations and ensure optimal usage of vailable space.
Spot availability checking:
. Users and the system should be able to check the availability of parking spots in real time.
Fee calculation:
. The system should calculate parking fees based on the duration of the parking session.
User Roles and Permission:
. The system will have different roles, Including Admin, Attendant, and User(vehicle owner).
. The Admins can configure parking lot setting, including pricing and flooor management.
. Attendants can check-in/check-out vehicles and mange spot assignments.
. Users can reserve spots, check availability, and view their parking history.
Support for Multiple floors:
. The system should manage parking sport across mutiple floors, allowing users to park on any available floor.
. Floor- specific features might include reserved spots for electric vehicles, handicapped speces, and charging stations.
Define Core Objects
Based on the requirements and use cases, identify the main objects of the system...
Analyze Relationships
Determine how these objects will interact with each other to fulfill the use cases...
- ParkingLot and Parking Floor:
- Parking lot contains mutiple Parking Floor.It manages the overall parking facility and delegates the task of finding an avilable spot to the appropriate floor
- ParkingFloor and ParkingSpot:
- Each parking floor contains mutiple ParkingSpot objects. The floor finds and assignn an available spot to a vehicle based on its size
- Parking spot and vehiccle
- a parking spot is eutger occupied by a vehicle or is vacant.When occupied, The spot stores a reference to the vehicle,
- Vehicle and Ticket:
- when a vehicle is paarked, a ticked is genreted, recoring the ntry time, the assigned spot, and the vehicle.The ticket is used to calcualte the parking fee.
- Ticket and paymjent:
- a payment is made for a ticket. The payment records the amount paid and marks the ticket as settle
- User and parkinglot system:
- user interact with the system based on their role(admin, attendant , regular user), performing actions like spot reservation, vehicle check-in/out, and view parking history.
Define Class Members (write code)
Attributes: For each class, define the attributes (data) it will hold...
Methods: Define the methods (functions) that operate on the attributes. Ensure they align with the object's responsibilities and adhere to the principle of encapsulation.
public class ParkingLot {
private static ParkingLot instance;
private List<ParkingFloor> floors;
private int totalSpots;
private int availableSpots;
private ParkingLot() {
this.floors = new ArrayList<>();
}
public static synchronized ParkingLot getInstance() {
if (instance == null) {
instance = new ParkingLot();
}
return instance;
}
public void addFloor(ParkingFloor floor) {
floors.add(floor);
totalSpots += floor.getTotalSpots();
availableSpots += floor.getAvailableSpots();
}
public ParkingSpot findAvailableSpot(Vehicle vehicle) {
for (ParkingFloor floor : floors) {
ParkingSpot spot = floor.findAvailableSpot(vehicle);
if (spot != null) return spot;
}
return null; // No spot available
}
public void releaseSpot(ParkingSpot spot) {
spot.removeVehicle();
availableSpots++;
}
// Other methods for managing the parking lot
}
public class ParkingFloor {
private int level;
private List<ParkingSpot> spots;
private int totalSpots;
private int availableSpots;
public ParkingFloor(int level, List<ParkingSpot> spots) {
this.level = level;
this.spots = spots;
this.totalSpots = spots.size();
this.availableSpots = calculateAvailableSpots();
}
public ParkingSpot findAvailableSpot(Vehicle vehicle) {
for (ParkingSpot spot : spots) {
if (!spot.isOccupied() && spot.getSize().equals(vehicle.getSize())) {
spot.assignVehicle(vehicle);
availableSpots--;
return spot;
}
}
return null; // No spot available
}
private int calculateAvailableSpots() {
int count = 0;
for (ParkingSpot spot : spots) {
if (!spot.isOccupied()) count++;
}
return count;
}
public int getTotalSpots() {
return totalSpots;
}
public int getAvailableSpots() {
return availableSpots;
}
// Other methods related to managing the floor
}
public class ParkingSpot {
private String spotId;
private String size;
private boolean isOccupied;
private Vehicle vehicle;
public ParkingSpot(String spotId, String size) {
this.spotId = spotId;
this.size = size;
this.isOccupied = false;
this.vehicle = null;
}
public void assignVehicle(Vehicle vehicle) {
this.vehicle = vehicle;
this.isOccupied = true;
}
public void removeVehicle() {
this.vehicle = null;
this.isOccupied = false;
}
public boolean isOccupied() {
return isOccupied;
}
public String getSize() {
return size;
}
// Other methods related to spot management
}
public abstract class Vehicle {
protected String licensePlate;
protected String size;
public Vehicle(String licensePlate, String size) {
this.licensePlate = licensePlate;
this.size = size;
}
public String getLicensePlate() {
return licensePlate;
}
public String getSize() {
return size;
}
// Other vehicle-related methods
}
public class Car extends Vehicle {
public Car(String licensePlate) {
super(licensePlate, "Medium");
}
}
public class Bike extends Vehicle {
public Bike(String licensePlate) {
super(licensePlate, "Small");
}
}
public class Truck extends Vehicle {
public Truck(String licensePlate) {
super(licensePlate, "Large");
}
}
public class Ticket {
private String ticketId;
private Vehicle vehicle;
private ParkingSpot spot;
private Date entryTime;
private Date exitTime;
private double fee;
public Ticket(String ticketId, Vehicle vehicle, ParkingSpot spot) {
this.ticketId = ticketId;
this.vehicle = vehicle;
this.spot = spot;
this.entryTime = new Date(); // Set entry time to current time
}
public void markExit() {
this.exitTime = new Date(); // Set exit time to current time
calculateFee();
}
private void calculateFee() {
// Fee calculation logic, possibly using a strategy pattern
long duration = exitTime.getTime() - entryTime.getTime(); // Duration in milliseconds
this.fee = duration * 0.05; // Example fee calculation
}
public double getFee() {
return fee;
}
// Other ticket-related methods
}
public class Payment {
private String paymentId;
private double amount;
private Date paymentTime;
private Ticket ticket;
public Payment(String paymentId, double amount, Ticket ticket) {
this.paymentId = paymentId;
this.amount = amount;
this.paymentTime = new Date(); // Set payment time to current time
this.ticket = ticket;
}
public boolean processPayment() {
// Payment processing logic
return true; // Assuming payment is successful
}
// Other payment-related methods
}
Establish Hierarchy
Design inheritance trees where applicable to promote code reuse and polymorphism. This step involves identifying common attributes and behaviors that can be abstracted into parent classes...
- Parking sport:
- create a base class called parkingspot that will contain common attributes like spotid,size and isoccupied
- we can then subclasses for different type of parking spots if needed, such as small,medium,large each ingeriting from parking spot.
- Vehicle:
- a base class vehicle will reporesent general attibutes like license plate and size
- subclasses like car , bike and truck can ingerit from vehicle to handle vehicle specfic details
- user:
- the user class will serve as a base clas with common attributes like useid, name and role
- subclass as as admin ,user can inherit use to implement role specific behaviors.
- ticket and payment:
- These classes do not require a hierarchical structure as they are specific to theri tasks.however , they ould implement common interface if the system were to grow, supporting different types of payments or ticket systems.
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.)...
Single Responsibility Principle
Each class in our design has a signle responsibility. For example , parking lot manages the overall parking lot, parking spot manages an indiviual spot, and Ticket handles parking tickets. The clear separation ensures taht changes in one aspect of the system don't affect other parts.
Open/closed principle(ocp)
The user of inferitance allows for extending functionality without modifying existing classes. For instance, new vehicle type eketruc cab ve added by creating new subclasses of vehicle without altering the existing vehicle class. similarly , new fee calcuation strategies can be added by implementing new fee stratgy classes.
Substitution principle
subclasses like car,bike and truck can be used interchangeably with the vehicle superclass. the system behavior remains consistent regardless of the specific vehicle type, adhering to LSP.
Interface Segregation principle
Although haven;t deine interfaces, our design ensures that classes only contain methods relevant to their specific role. For example , vehicle only includes methods related to vehicle characteristics, and parkingspot focuss on spot mangement.
Dependency inversion principle
the use of startegies for fee calculation allow high level classes like ticket to depend on abstration rather than concrete implementations. this make the system more flexible and easier to modify or extend.
Future improvements
To future proof can consider manageing multiple carpark.