Based on the requirements and use cases, identify the main objects of the system and analyze how they interact and relate to each other...
public abstarct class vechile{
private String licencePlate;
private String type;
public vechile(String licencePlate, String type){
this.licencePlate= licencePlate;
this.type= type;
}}
we will implement it like
public class car extend vechile{
public car(String licnecplate){
super(licenceplate, vechiletype.car)
}
}
we make oject vechioe type
public enum vechiletype{
MotorCycle(1), Car(2), Truck(3);
private final int size;
vechiletype(int size){
this.size=size;
}
public int getseize(){
return size;
}
}
public enum spottype{
SMALL(1), MEDIUM(2), LARGE(3);
private final int size;
spottype(int size){
this.size=size;
}
public int getseize(){
return size;
}
}
Now we will do pricing startegy. we weill use interface and impliment our funciton with that.
public interface PricingStrategy{
double calculateFee(long durationMinutes, VehicleType vehicleType);
}
public class hourlypricing impliment PricingStrategy{
private final Map<vechiletype, doube> hourlyrates;
public hourlypricing(Map<vechiletype, doube> hourlyrates){
this.hourlyrates=hourlyrates;
}
@override
public double calculateFee(long durationMinutes, VehicleType vehicleType){
double hours = Math.ceil(durationMinutes / 60.0);
return hours * hourlyRates.getOrDefault(
vehicleType, 5.0);
}
}
public class FlatRatePricing implements PricingStrategy {
private final double flatRate;
public FlatRatePricing(double flatRate) {
this.flatRate = flatRate;
}
@Override
public double calculateFee(long durationMinutes,
VehicleType vehicleType) {
return flatRate;
}
}
public class AdvanceBookingPricing
implements PricingStrategy {
private final double bookingCharge;
private final double hourlyRate;
public AdvanceBookingPricing(
double bookingCharge,
double hourlyRate) {
this.bookingCharge = bookingCharge;
this.hourlyRate = hourlyRate;
}
@Override
public double calculateFee(
long durationMinutes,
VehicleType vehicleType) {
double hours =
Math.ceil(durationMinutes / 60.0);
return bookingCharge + (hours * hourlyRate);
}
}
Now we define parking spot object
class parkingSpot{
private final string id;
private final SpotType spotType;
private boolean isAvailable;
private Vehicle assignedVehicle;
public parkingSpot(string id, SpotType spotType ){
this.id= id;
this.spotType= spotType;
}
public boolean canFit(Vehicle vehicle){
if(!isAvailable){
return false;
this.assignedVehicle= vehicle;
this.isAvailable=false;
return true;
}
}
public synchorized void release(){
this.assignedVehicle= null;
this.isAvailable=true;
}
public String getId() { return id; }
public SpotType getSpotType() { return spotType; }
public boolean isAvailable() { return isAvailable; }
public Vehicle getAssignedVehicle() { return assignedVehicle; }
}
}
now we will make object o fparking ticket
public class parkingTicket{
private final String ticketId;
private final Vehicle vehicle;
private final ParkingSpot spot; private final LocalDateTime entryTime;
private LocalDateTime exitTime;
public ParkingTicket(String ticketId, Vehicle vehicle,
ParkingSpot spot) {
this.ticketId = ticketId;
this.vehicle = vehicle;
this.spot = spot;
this.entryTime = LocalDateTime.now();
}
}
int double calculateFee(PricingStrategy strategy){
if(exitTime==null){
exitTime = LocalDateTime.now();
}
long minutes = Duration.between(entryTime, exitTime)
.toMinutes();
return strategy.calculateFee(minutes, vehicle.getType());
}
public void setExitTime(LocalDateTime exitTime) {
this.exitTime = exitTime;
}
public String getTicketId() { return ticketId; }
public Vehicle getVehicle() { return vehicle; }
public ParkingSpot getSpot() { return spot; }
public LocalDateTime getEntryTime() { return entryTime; }
}
public class ParkingFloor {
private final String floorId;
private final List<ParkingSpot> spots;
public ParkingFloor(String floorId, List<ParkingSpot> spots) {
this.floorId = floorId;
this.spots = spots;
}
public ParkingSpot findAvailableSpot(VehicleType vehicleType) {
for (ParkingSpot spot : spots) {
if (spot.isAvailable()
&& spot.getSpotType().getSize()
>= vehicleType.getSize()) {
return spot;
}
}
return null;
}
public String getFloorId() { return floorId; }
public List<ParkingSpot> getSpots() { return spots; }
}
public class ParkingLot {
private final List
private final PricingStrategy pricingStrategy;
private final Map
private final AtomicInteger ticketCounter;
private final ReentrantLock entryLock;
public ParkingLot(List
PricingStrategy pricingStrategy) {
this.floors = floors;
this.pricingStrategy = pricingStrategy;
this.activeTickets = new ConcurrentHashMap<>();
this.ticketCounter = new AtomicInteger(0);
this.entryLock = new ReentrantLock();
}
public ParkingTicket enter(Vehicle vehicle) {
entryLock.lock();
try {
for (ParkingFloor floor : floors) {
ParkingSpot spot = floor.findAvailableSpot(
vehicle.getType());
if (spot != null && spot.assign(vehicle)) {
String ticketId = "T-"
+ ticketCounter.incrementAndGet();
ParkingTicket ticket = new ParkingTicket(
ticketId, vehicle, spot);
activeTickets.put(ticketId, ticket);
return ticket;
}
}
throw new RuntimeException(
"Parking lot is full for vehicle type: "
+ vehicle.getType());
} finally {
entryLock.unlock();
}
}
public double exit(ParkingTicket ticket) {
ticket.setExitTime(LocalDateTime.now());
double fee = ticket.calculateFee(pricingStrategy);
ticket.getSpot().release();
activeTickets.remove(ticket.getTicketId());
return fee;
}
public boolean isFull() {
for (ParkingFloor floor : floors) {
for (ParkingSpot spot : floor.getSpots()) {
if (spot.isAvailable()) return false;
}
}
return true;
}
}
For each class, define the attributes (data) it will hold and the methods (functions) that operate on the attributes. Ensure they align with the object's responsibilities and adhere to the principle of encapsulation. Write your code in the code editor below.
Explain design tradeoffs you considered. Check and explain whether your design adheres to SOLID principles. Explain how your design can handle changes in scale and whether it would be easy to extend with new functionalities. Identify areas for future improvement...