Loading...
The parking lot system will allow different vehicle in size entering and leaving the parking lot that is consisted of multiple floors and various types of spot. The system will handle spot assignment and fee calculation based on parking duration. The main functionalities are:
public class VehicleFactory {
public static Vehicle createVehicle(VehicleType type, String licensePlate) {
switch(type) {
case CAR:
return new Car(licensePlate);
case MOTORCYCLE:
return new Motorcycle(licensePlate);
case VAN:
return new Van(licensePlate);
case ELECTRIC:
return new Electric(licensePlate);
case TRUCK:
return new Truck(licensePlate);
default:
throw new IllegalArgumentException("Unknown vehicle type: " + type);
}
}
}
public class ParkingSpotFactory{
public static createParkingSpot(ParkingSpotType type){
switch(type){
case LARGE:
return new Large();
}
}
}
public class ParkingLot{
private static ParkingLot instatnce;
private ParkingLot(){
}
public static synchronized ParkingLog getInstance(){
if(instance==null){
instance=new ParkingLot();
}
return instance;
}
}
public interface FeeStrategy{
double calculateFee();
}
public class RegularFeeStrategy implements FeeStrategy{
@Override
double calculateFee(int baseFee, int feeFactor, Ticket ticket){
return baseFee+feeFactor*(ticket.exitTime-ticketEntryTime);
}
}
public class VehicleFactory {
public static Vehicle createVehicle(VehicleType type, String licensePlate) {
switch(type) {
case CAR:
return new Car(licensePlate);
case MOTORCYCLE:
return new Motorcycle(licensePlate);
case VAN:
return new Van(licensePlate);
case ELECTRIC:
return new Electric(licensePlate);
case TRUCK:
return new Truck(licensePlate);
default:
throw new IllegalArgumentException("Unknown vehicle type: " + type);
}
}
}
public abstract class Vehicle{
String licensePlate;
VehicleType type;
Ticket ticket;
public Vehicle(String _lp, VehicleType _type, Ticket ticket){
this.licensePlate=licensePlate;
this.type=_type;
this.ticket=ticket;
}
}
public class Car extends Vehicle{
public Car(String licensePlate, Ticket ticket){
super(licensePlate,VehicleType.CAR,ticket);
}
}
public class ParkingSpotFactory{
public static createParkingSpot(ParkingSpotType type){
switch(type){
case LARGE:
return new Large();
}
}
}
public abstract class ParkingSpot{
int id;
ParkingSpotType type;
boolean isFree;
public ParkingSpot(ParkingSpotType type){
this.type=type;
isFree=true;
}
public boolean getIsFree(){
return isFree;
}
}
public class LargeSpot extends ParkingSpot{
super(ParkingSpotType.LARGE_SPOT);
}
public interface FeeStrategy{
double calculateFee();
}
public class RegularFeeStrategy implements FeeStrategy{
@Override
double calculateFee(Ticket ticket){
int baseFee=10, int feeFactor=1;
return baseFee+feeFactor*(ticket.exitTime-ticketEntryTime);
}
}
public class Ticket{
int ticketId;
DateTime entryTime, exitTime;
ParkingTicketStatus status;
FeeStrategy feeStratety;
public Ticket(DateTime entryTime, FeeStrategy feeStrategy){
this.entryTime=entryTime;
this.status=ParkingTicketStatus.ACTIVE;
this.feeStrategy=feeStrategy;
}
}
public class ParkingFloor{
int floorNum;
List<ParkingSpot> availableSpots;
Map<Vehicle, ParkingSpot> map_vehicle2Spot;
public ParkingFloor(int floorNum){
this.floorNum=floorNum;
availableSpots=new LinkedList<>();
map_vehicle2Spots=new HashMap<>();
}
public void freeSpot(Vehicle vehicle){
ParkingSpot spot=map_vehicle2Spots.get(vehicle);
availableSpots.add(spot);
map_vehicle2Spots.remove(vehicle);
}
public void assignSpot(Vechile vehicle){
map_vehicle2Spots.put(vehicle, availableSpots.get(availableSpots.size()-1));
availableSpots.remove(availableSpots.size()-1);
}
}
public class ParkingLot{
String name;
List<ParkingFloor> floors;
Map<Vehicle, ParkingFloor> map_vehicle2Floor;
private static ParkingLot instance;
private ParkingLot(String name){
this.name=name;
floors=new ArrayList<>();
map_vehicle2Floor=new HashMap<>();
}
public static synchronized getInstance(String name){
if(instance==null) instance=new ParkingLot(name);
return instance;
}
public void addFloor(){
ParkingFloor newFloor=new ParkingFloor(floors.size());
//skip adding spots
floors.add(newFloor)
}
public void enterParkingLot(Vehicle vehicle){
for(ParkingFloor floor:floors){
if(floor.availableSpots.size()>0){
DateTime curTime=new Date();
Ticket curTicket=new Ticket(curTime, new RegularFeeStrategy);
vehicle.ticket=curTicket;
floor.assignSpot(vehicle);
map_vehicle2Spot.put(vehicle,floor);
}
}
}
public void exitParkingLot(Vehicle vehicle){
Ticket ticket=vehicle.ticket;
ticket.feeStratege.claculateFee(ticket);
ParkingFloor floor=map_vehicle2Spot.get(vehicle);
floor.freeSpot(vehicle);
map_vehicle2Spot.remove(vehicle);
}
}
ParkingLot manages the overall parking lot, ParkingSpot manages an individual spot, and Ticket handles parking tickets. This clear separation ensures that changes in one aspect of the system don’t affect other parts.ElectricCar) can be added by creating new subclasses of Vehicle without altering the existing Vehicle class. Similarly, new fee calculation strategies can be added by implementing new FeeStrategy classes.Car, Bike, and Truck can be used interchangeably with the Vehicle superclass. The system’s behavior remains consistent regardless of the specific vehicle type, adhering to LSP.FeeStrategy interface) allows high-level classes like Ticket to depend on abstractions rather than concrete implementations. This makes the system more flexible and easier to modify or extend.