Progettare un parcheggio utilizzando i principi orientati agli oggetti comporta la scomposizione del sistema in classi, attributi e metodi che riflettono le entità del mondo reale. Componenti chiave come veicoli e parcheggi possono essere modellati come oggetti mentre le interazioni come il parcheggio possono essere gestite attraverso metodi. Questo approccio promuove la modularità, la riusabilità e la manutenibilità, rendendo il sistema facile da estendere e gestire.
Come progettare un parcheggio utilizzando i principi orientati agli oggetti?Ipotesi
Per i nostri scopi adesso faremo le seguenti ipotesi. Abbiamo fatto queste ipotesi specifiche per aggiungere un po' di complessità al problema senza aggiungere troppo.
- Il parcheggio ha più livelli. Ogni livello ha più file di punti.
- Nel parcheggio è possibile parcheggiare moto, auto e pullman.
- Il parcheggio dispone di posti moto, posti compatti e posti grandi.
- Una moto può parcheggiare ovunque.
- Un'auto può parcheggiare sia in un unico posto compatto che in un unico posto grande.
- Un autobus può parcheggiare in cinque grandi parcheggi consecutivi e all'interno della stessa fila. Non è possibile parcheggiare in spazi ristretti. Nell'implementazione seguente abbiamo creato una classe astratta Vehicle da cui ereditano Car Bus e Motorcycle.
Design orientato agli oggetti
Iniziamo creando le classi necessarie e assicurandoci che ciascuna classe abbia una chiara responsabilità unica. Analizziamo la progettazione concentrandoci su come interagisce ciascuna classe e metodo.
1. Classe del veicolo
ILVehicleLa classe definisce attributi e comportamenti comuni per tutti i tipi di veicoli. Servirà come classe base per tipi di veicoli più specifici comeBus CarEMotorcycle.
public abstract class Vehicle { protected String licensePlate; protected int spotsNeeded; protected VehicleSize size; public Vehicle(String licensePlate VehicleSize size) { this.licensePlate = licensePlate; this.size = size; this.spotsNeeded = (size == VehicleSize.Large) ? 5 : 1; } public int getSpotsNeeded() { return spotsNeeded; } public VehicleSize getSize() { return size; } public String getLicensePlate() { return licensePlate; } public abstract boolean canFitInSpot(ParkingSpot spot); }
2. Classi di veicoli concreti
Autobus : Un autobus richiede 5 punti grandi consecutivi.
Javapublic class Bus extends Vehicle { public Bus(String licensePlate) { super(licensePlate VehicleSize.Large); } public boolean canFitInSpot(ParkingSpot spot) { return spot.getSpotSize() == VehicleSize.Large; } }
Auto : Un'auto può parcheggiare sia in spazi compatti che ampi.
Javapublic class Car extends Vehicle { public Car(String licensePlate) { super(licensePlate VehicleSize.Compact); } public boolean canFitInSpot(ParkingSpot spot) { return spot.getSpotSize() == VehicleSize.Compact || spot.getSpotSize() == VehicleSize.Large; } }
Motociclo : Una moto può parcheggiare ovunque
Javapublic class Motorcycle extends Vehicle { public Motorcycle(String licensePlate) { super(licensePlate VehicleSize.Motorcycle); } public boolean canFitInSpot(ParkingSpot spot) { return true; // Can park in any spot } }
3. Classe ParkingSpot
ILParkingSpotla classe rappresenta un posto auto individuale nel parcheggio. È responsabile della gestione della sua disponibilità e della verifica se un veicolo specifico può adattarsi al posto.
- Avremmo potuto implementarlo avendo classi per LargeSpot CompactSpot e MotorcycleSpot che ereditano da ParkingSpot ma questo è probabilmente eccessivo.
- Le macchie probabilmente non hanno comportamenti diversi oltre alle loro dimensioni.
public class ParkingSpot { private Vehicle vehicle; private VehicleSize spotSize; private int row; private int spotNumber; private Level level; public ParkingSpot(Level level int row int spotNumber VehicleSize spotSize) { this.level = level; this.row = row; this.spotNumber = spotNumber; this.spotSize = spotSize; this.vehicle = null; } public boolean isAvailable() { return vehicle == null; } public boolean canFitVehicle(Vehicle vehicle) { return isAvailable() && vehicle.canFitInSpot(this); } public void parkVehicle(Vehicle vehicle) { if (canFitVehicle(vehicle)) { this.vehicle = vehicle; } } public void removeVehicle() { this.vehicle = null; } public VehicleSize getSpotSize() { return spotSize; } public int getRow() { return row; } public int getSpotNumber() { return spotNumber; } }
4. Classe ParkingLevel
ILLevella classe rappresenta un livello nel parcheggio. Gestisce una serie di parcheggi e fornisce metodi per parcheggiare e rimuovere i veicoli.
public class Level { private int levelNumber; private ParkingSpot[] spots; public Level(int levelNumber int numSpots) { this.levelNumber = levelNumber; this.spots = new ParkingSpot[numSpots]; } public boolean parkVehicle(Vehicle vehicle) { for (ParkingSpot spot : spots) { if (spot.canFitVehicle(vehicle)) { spot.parkVehicle(vehicle); return true; } } return false; } public boolean removeVehicle(Vehicle vehicle) { for (ParkingSpot spot : spots) { if (spot.isOccupied() && spot.getVehicle().equals(vehicle)) { spot.removeVehicle(); return true; } } return false; } }
5. Classe parcheggio
ILParkingLotla classe rappresenta l'intero parcheggio. Gestisce più livelli e fornisce metodi per parcheggiare e rimuovere i veicoli dal parcheggio.
public class ParkingLot { private Level[] levels; public ParkingLot(int numLevels int numSpotsPerLevel) { levels = new Level[numLevels]; for (int i = 0; i < numLevels; i++) { levels[i] = new Level(i numSpotsPerLevel); } } public boolean parkVehicle(Vehicle vehicle) { for (Level level : levels) { if (level.parkVehicle(vehicle)) { return true; } } return false; // Parking failed (no spots available) } public boolean removeVehicle(Vehicle vehicle) { for (Level level : levels) { if (level.removeVehicle(vehicle)) { return true; } } return false; // Removal failed (vehicle not found) } }
6. Classi di servizi di biglietteria e pagamento
Per gestire la biglietteria e i pagamenti aggiungiamo ilTicketEPaymentServiceclassi.
Classe del biglietto : Rappresenta il biglietto emesso al momento della sosta del veicolo. Registra l'ora in cui il veicolo entra ed esce dal parcheggio.
Javapublic class Ticket { private Vehicle vehicle; private Date issueTime; private Date exitTime; public Ticket(Vehicle vehicle) { this.vehicle = vehicle; this.issueTime = new Date(); } public void setExitTime(Date exitTime) { this.exitTime = exitTime; } public long getDuration() { return (exitTime.getTime() - issueTime.getTime()) / 1000; // Time in seconds } }
Classe del servizio di pagamento : Responsabile del calcolo della tariffa del parcheggio e dell'elaborazione dei pagamenti.
Giavapubblico classe Servizio di pagamento { pubblico raddoppiare calcolatariffa(Biglietto biglietto) { lungo durata = biglietto.getDuration(); // Modello tariffario semplice: `text`=